package com.corpgovernment.organization.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.corpgovernment.api.applytrip.enums.ApplyTripEmployeeEnum;
import com.corpgovernment.api.operatelog.util.OperateLogContentUtil;
import com.corpgovernment.api.operatelog.vo.OperateLogContentDataVo;
import com.corpgovernment.api.organization.bo.FindManageFuzzyRequestBO;
import com.corpgovernment.api.organization.bo.SearchEmployeeInfoRequestBO;
import com.corpgovernment.api.organization.bo.UpdateEmployeeRequestBO;
import com.corpgovernment.api.organization.bo.UpdateEmployeeResponseBO;
import com.corpgovernment.api.organization.dto.EmployeeBirthVo;
import com.corpgovernment.api.organization.dto.EmployeeCardVo;
import com.corpgovernment.api.organization.dto.EmployeeInfoVo;
import com.corpgovernment.api.organization.dto.request.EmployeeByUidRequestVo;
import com.corpgovernment.api.organization.enums.CardTypeEnum;
import com.corpgovernment.api.organization.enums.UserOrgRelationStatusEnum;
import com.corpgovernment.api.organization.model.base.PageInfoResponse;
import com.corpgovernment.api.organization.model.bookingrelation.UidOrgIdEntry;
import com.corpgovernment.api.organization.model.employee.EmployeeInfoBo;
import com.corpgovernment.api.organization.model.employee.EmployeeInfoConditionVO;
import com.corpgovernment.api.organization.model.employee.ListEmployeeByConditionRequest;
import com.corpgovernment.api.organization.model.employee.ListEmployeeByConditionResponse;
import com.corpgovernment.api.organization.model.idcard.UserIdCardVo;
import com.corpgovernment.api.organization.model.org.queryEmployee.EmployeeDTO;
import com.corpgovernment.api.organization.model.org.queryEmployee.QueryEmployeeRequest;
import com.corpgovernment.api.organization.model.org.queryEmployee.QueryEmployeeResponse;
import com.corpgovernment.api.organization.model.passenger.MobilePhoneVo;
import com.corpgovernment.api.organization.model.settlement.QueryEmployeeInfoWithPermissionRequest;
import com.corpgovernment.api.organization.model.settlement.QueryEmployeeInfoWithPermissionResponse;
import com.corpgovernment.api.organization.model.user.NameInfoBo;
import com.corpgovernment.api.organization.model.user.employee.EmployeeInfoResponseBo;
import com.corpgovernment.api.organization.model.user.employee.EmployeeOrgVo;
import com.corpgovernment.api.organization.model.user.employee.OrgEmployeeVo;
import com.corpgovernment.api.organization.model.user.employee.OrgPostLogVo;
import com.corpgovernment.api.organization.model.user.employee.front.EmployeeOpratLogVo;
import com.corpgovernment.api.organization.model.user.employee.front.SubmitSelectEmpVo;
import com.corpgovernment.api.organization.model.user.employee.response.GetUserInfoResponse;
import com.corpgovernment.api.permission.soa.IUserPermissionClient;
import com.corpgovernment.api.permission.vo.GetUserRoleDetailRequest;
import com.corpgovernment.api.permission.vo.GetUserRoleListInfo;
import com.corpgovernment.api.permission.vo.GetUserRoleListResponse;
import com.corpgovernment.common.apollo.OrganizationApollo;
import com.corpgovernment.common.base.BaseUserInfo;
import com.corpgovernment.common.base.CommonException;
import com.corpgovernment.common.base.JSONResult;
import com.corpgovernment.common.base.ResourceInfo;
import com.corpgovernment.common.common.CorpBusinessException;
import com.corpgovernment.common.enums.ExceptionCodeEnum;
import com.corpgovernment.common.operatelog.constant.OperateLogContant;
import com.corpgovernment.common.utils.DataPermissions.DataPermissionsContext;
import com.corpgovernment.common.utils.Md5Util;
import com.corpgovernment.job.dao.entity.db.EmployeeJobRelationDo;
import com.corpgovernment.job.dao.entity.db.JobDo;
import com.corpgovernment.job.service.JobService;
import com.corpgovernment.organization.constant.OrganizationResponseCodeEnum;
import com.corpgovernment.organization.dataloader.db.*;
import com.corpgovernment.organization.dto.ListEmployeeQuery;
import com.corpgovernment.organization.dto.OrgUserInfoPk;
import com.corpgovernment.organization.dto.UserEmailDTO;
import com.corpgovernment.organization.entity.db.*;
import com.corpgovernment.organization.enumm.CardCodeEnum;
import com.corpgovernment.organization.enumm.OrgTypeEnum;
import com.corpgovernment.organization.enumm.ServiceErrorEnum;
import com.corpgovernment.organization.enumm.StaffStatusEnum;
import com.corpgovernment.organization.mapper.MbOrgEmployeeMapper;
import com.corpgovernment.organization.mapper.MbOrgInfoMapper;
import com.corpgovernment.organization.mapper.MbPostMapper;
import com.corpgovernment.organization.mapper.MbUserOrgRelationMapper;
import com.corpgovernment.organization.model.MbUserOrgRelationModel;
import com.corpgovernment.organization.operatelog.service.pojo.OperateLogPojo;
import com.corpgovernment.organization.operatelog.service.pojo.StaffAddPojo;
import com.corpgovernment.organization.service.*;
import com.corpgovernment.organization.util.CardTypeSwitchUtil;
import com.corpgovernment.organization.util.EmployeeInfoHandleUtils;
import com.corpgovernment.organization.util.IdCardUtil;
import com.corpgovernment.organization.util.TokenValidUtil;
import com.corpgovernment.organization.vo.SearchCorpEmpResponse;
import com.corpgovernment.permission.service.RoleService;
import com.corpgovernment.permission.vo.UserRole;
import com.ctrip.corp.obt.generic.core.context.RequestContext;
import com.ctrip.corp.obt.generic.core.context.UserInfoContext;
import com.ctrip.corp.obt.generic.notification.annotation.InfoChange;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import com.ctrip.corp.obt.shard.configuration.Config;
import com.ctrip.corp.obt.shard.context.PageContext;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.pagination.IPage;
import com.ctrip.corp.obt.shard.sql.mybatis.interceptor.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.corpgovernment.api.applytrip.enums.ApplyTripEmployeeEnum.*;
import static com.corpgovernment.organization.constant.OrganizationResponseCodeEnum.DOWNLOAD_EMPLOYEE_INFO_ERROR;
import static com.corpgovernment.organization.constant.OrganizationResponseCodeEnum.EMPLOYEE_GET_REQUEST_IS_NULL;
import static com.corpgovernment.organization.controller.OrganizationEmployeeController.idMask;
import static com.corpgovernment.permission.config.PermissionFilter.DATA_PERMISSION_ORG_ID_LIST;

/**
 * 员工用户信息service实现
 *
 * @author wangyujue
 */
@Service
@Slf4j
public class OrganizationEmployeeServiceImpl extends OrganizationBaseService implements IOrganizationEmployeeService {

    @Autowired
    private MbOrgEmployeeMapper orgEmployeeMapper;
    @Autowired
    private IUserOrgRelationService userOrgRelationService;
    @Autowired
    private IPostService postService;
    @Autowired
    private IOrgUserIdCardService organizationUserIdCardService;
    @Autowired
    private IOrganizationUserFfpService organizationUserFfpService;
    @Autowired
    private com.corpgovernment.organization.service.IOrganizationInfoService organizationInfoService;
    @Autowired
    private IUserPermissionClient userPermissionService;
    @Autowired
    private com.corpgovernment.permission.service.UserRoleService userRoleService;
    @Autowired
    private IUserLoginService userLoginService;
    @Autowired
    private IFreshPassengerService freshPassengerService;
    @Autowired
    private FreshPassengerRelationServiceImpl freshPassengerRelationService;
    @Autowired
    private MbOrgInfoMapper orgInfoMapper;
    @Autowired
    private MbUserOrgRelationMapper userOrgRelationMapper;
    @Autowired
    private MbOrgEmployeeLoader mbOrgEmployeeLoader;
    @Autowired
    private TokenValidUtil tokenValidUtil;
    @Autowired
    private RedemptionCodeService redemptionCodeService;
    @Autowired
    private MbOrgInfoMapper mbOrgInfoMapper;

    @Autowired
    private MbOrgUserIdcardLoader mbOrgUserIdcardLoader;
    @Autowired
    protected MbOrgInfoLoader mbOrgInfoLoader;
    @Autowired
    private EmployeeInfoHandleUtils employeeInfoHandleUtils;
    @Autowired
    protected MbOrgNonEmployeeLoader mbOrgNonEmployeeLoader;
    @Autowired
    protected IOrgUserIdCardService orgUserIdCardService;
    @Autowired
    private MbUserOrgRelationLoader mbUserOrgRelationLoader;
    @Autowired
    private MbPostMapper mbPostMapper;
    @Autowired
    private OrganizationApollo organizationApollo;
    @Autowired
    private JobService jobService;
    @Autowired
    private RoleService roleService;
    @Autowired
    @Qualifier(value = "defaultThreadPoolExecutor")
    private ThreadPoolExecutor defaultThreadPoolExecutor;
    @Autowired
    private MbEmployeeJobRelationLoader employeeJobRelationLoader;

    private static final Integer MAX_RECURSION_TIMES = 50;

    /**
     * 转化为日志需要的对象
     *
     * @param employeeInfo
     * @return
     */
    public OperateLogPojo convertStaffLogPojo(StaffAddPojo employeeInfo) {
        try {
            String orgId = employeeInfo.getOrgId();
            String condition = employeeInfo.getMobilePhone();
            Integer pageNum = 1;
            Integer pageSize = 20;
            ListEmployeeQuery listEmployeeQuery = new ListEmployeeQuery();
            listEmployeeQuery.setPageNum(pageNum);
            listEmployeeQuery.setPageSize(pageSize);
            List<MbOrgEmployeeInfo> employeeInfoList = CollUtil.newArrayList();
            if (StrUtil.isNotBlank(condition)) {
                listEmployeeQuery.setQuery(condition);
                employeeInfoList = userOrgRelationService.listByQuery(listEmployeeQuery, null);
            } else {
                listEmployeeQuery.setOrgId(orgId);
                employeeInfoList = userOrgRelationService.listByQuery(listEmployeeQuery, null);
            }
            if (CollectionUtils.isEmpty(employeeInfoList)) {
                log.error("查询人员信息为空");
                return null;
            }
            // 通过组织结构id查询出员工信息列表

            MbOrgInfo mbOrgInfo = organizationInfoService.findByOrgId(orgId);
            //查询角色
            Set<UidOrgIdEntry> uidOrgIdEntries = new HashSet<>();
            UidOrgIdEntry uidOrgIdEntry = null;
            for (MbOrgEmployeeInfo mbOrgEmployeeInfo : employeeInfoList) {
                uidOrgIdEntry = new UidOrgIdEntry();
                uidOrgIdEntry.setOrgId(mbOrgEmployeeInfo.getOrgId());
                uidOrgIdEntry.setUid(mbOrgEmployeeInfo.getUid());
                uidOrgIdEntries.add(uidOrgIdEntry);
            }
            Map<UidOrgIdEntry, List<UserRole>> roleMap = null;
            if (!CollectionUtils.isEmpty(uidOrgIdEntries)) {
                roleMap = userRoleService.queryRoles(uidOrgIdEntries);
            }
            // 查询人的证件信息
            List<String> uids = employeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
            List<MbOrgUserIdcard> userIdcards = organizationUserIdCardService.batchFindByUids(uids);
            Map<String, List<MbOrgUserIdcard>> userCardMap = MapUtil.newHashMap();
            if (CollUtil.isNotEmpty(userIdcards)) {
                userCardMap = userIdcards.stream().sorted((a, b) -> b.getDatachangeLasttime().compareTo(a.getDatachangeLasttime())).collect(Collectors.groupingBy(MbOrgUserIdcard::getEmployeeUid));
            }
            List<OrgEmployeeVo> employeeList = CollUtil.newArrayList();
            // 循环封装数据
            OrgEmployeeVo orgEmployeeVo = null;
            for (MbOrgEmployeeInfo mbOrgEmployeeInfo : employeeInfoList) {
                orgEmployeeVo = new OrgEmployeeVo();
                orgEmployeeVo.setUid(mbOrgEmployeeInfo.getUid());
                orgEmployeeVo.setName(mbOrgEmployeeInfo.getName());
                orgEmployeeVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
                orgEmployeeVo.setAreaCode(mbOrgEmployeeInfo.getAreaCode());
                List<MbOrgUserIdcard> idcards = userCardMap.get(mbOrgEmployeeInfo.getUid());
                List<GetUserInfoResponse.CardInfo> cardInfoList = new ArrayList<>();
                if (CollUtil.isNotEmpty(idcards)) {
                    GetUserInfoResponse.CardInfo cardInfoVo = null;
                    for (MbOrgUserIdcard mbOrgUserIdcard : idcards) {
                        cardInfoVo = new GetUserInfoResponse.CardInfo();
                        orgEmployeeVo.setCardType(mbOrgUserIdcard.getCardType());
                        // 证件号加密
                        String encryptStr = encryptCardNo(mbOrgUserIdcard.getCardNo(), mbOrgUserIdcard.getCardType());
                        orgEmployeeVo.setCardNo(encryptStr);
                        cardInfoVo.setCardType(mbOrgUserIdcard.getCardType());
                        cardInfoVo.setCardNo(encryptStr);
                        cardInfoList.add(cardInfoVo);
                    }
                    orgEmployeeVo.setCardList(cardInfoList);
                }
                List<UserRole> userRoles = roleMap.get(new UidOrgIdEntry(mbOrgEmployeeInfo.getUid(), mbOrgEmployeeInfo.getOrgId()));
                if (CollectionUtils.isNotEmpty(userRoles)) {
                    orgEmployeeVo.setRoleInfo(userRoles.stream().map(x -> x.getRoleName()).collect(Collectors.toList()));
                }
                orgEmployeeVo.setIsLeader(mbOrgEmployeeInfo.getIsLeader() == null ? false : mbOrgEmployeeInfo.getIsLeader());
                orgEmployeeVo.setStatus(mbOrgEmployeeInfo.getStatus());
                // 职级
                Long postId = mbOrgEmployeeInfo.getPostId();
                if (postId != null) {
                    MbPostInfo mbPostInfo = postService.find(postId);
                    orgEmployeeVo.setRank(mbPostInfo.getName());
                }
                orgEmployeeVo.setOrgId(mbOrgEmployeeInfo.getOrgId());
                orgEmployeeVo.setPostId(mbOrgEmployeeInfo.getPostId());
                break;
            }
            if (orgEmployeeVo != null) {
                OperateLogPojo operateLogPojo = JsonUtils.convert(orgEmployeeVo, OperateLogPojo.class);
                List<GetUserInfoResponse.CardInfo> cardList = orgEmployeeVo.getCardList();
                GetUserInfoResponse.CardInfo cardInfo = null;
                if (CollectionUtils.isNotEmpty(cardList)) {
                    cardInfo = cardList.get(0);
                }

                if (cardInfo != null) {
                    StringBuffer stringBuffer = new StringBuffer();
                    stringBuffer.append(CardCodeEnum.get(String.valueOf(cardInfo.getCardType())).getDesc()).append(" ").append(cardInfo.getCardNo());
                    operateLogPojo.setCardType(stringBuffer.toString());
                }

                operateLogPojo.setIsCharge(orgEmployeeVo.getIsLeader() ? OperateLogContant.TRUE : OperateLogContant.FALSE);
                StringBuffer stringBuffer = new StringBuffer();
                stringBuffer.append(orgEmployeeVo.getAreaCode()).append(" ").append(orgEmployeeVo.getMobilePhone());
                operateLogPojo.setPhone(stringBuffer.toString());
                operateLogPojo.setRoleInfo(JsonUtils.toJsonString(orgEmployeeVo.getRoleInfo()));
                operateLogPojo.setOrgName(mbOrgInfo.getName());
                operateLogPojo.setStatus(StaffStatusEnum.get(orgEmployeeVo.getStatus() == null ? 1 : orgEmployeeVo.getStatus()).getDesc());
                operateLogPojo.setSta(employeeInfo.getSta());
                return operateLogPojo;
            }

        } catch (Exception e) {
            log.error("修改人员信息操作日志失败，原因:{}", e.getMessage(), e);
            return null;
        }
        return null;
    }

    @Override
    public List<OrgPostLogVo> queryAdminLog(List<String> uids, String orgId) {
        MbOrgInfo mbOrgInfo = organizationInfoService.findByOrgId(orgId);
        List<OrgPostLogVo> orgPostLogList = Lists.newArrayList();
        for (String uid : uids) {
            MbOrgEmployeeInfo mbOrgEmployeeInfo = findByUid(uid);
            OrgPostLogVo orgPostLogVo = null;
            if (mbOrgEmployeeInfo != null) {
                // 查询人的证件信息
                List<MbOrgUserIdcard> userIdcards = organizationUserIdCardService.batchFindByUids(uids);
                Map<String, List<MbOrgUserIdcard>> userCardMap = MapUtil.newHashMap();
                if (CollUtil.isNotEmpty(userIdcards)) {
                    userCardMap = userIdcards.stream().sorted((a, b) -> b.getDatachangeLasttime().compareTo(a.getDatachangeLasttime())).collect(Collectors.groupingBy(MbOrgUserIdcard::getEmployeeUid));
                }
                OrgPostLogVo orgEmployeeVo = new OrgPostLogVo();
                orgEmployeeVo.setId(mbOrgEmployeeInfo.getId());
                orgEmployeeVo.setUid(mbOrgEmployeeInfo.getUid());
                orgEmployeeVo.setName(mbOrgEmployeeInfo.getName());
                orgEmployeeVo.setPhone("+" + mbOrgEmployeeInfo.getAreaCode() + " " + mbOrgEmployeeInfo.getMobilePhone());
                List<MbOrgUserIdcard> idcards = userCardMap.get(mbOrgEmployeeInfo.getUid());
                if (CollUtil.isNotEmpty(idcards)) {
                    MbOrgUserIdcard mbOrgUserIdcard = idcards.get(0);
                    CardCodeEnum cardCodeEnum = CardCodeEnum.get(String.valueOf(mbOrgUserIdcard.getCardType()));
                    orgEmployeeVo.setCardType(cardCodeEnum.getDesc());
                    // 证件号加密
                    String encryptStr = encryptCardNo(mbOrgUserIdcard.getCardNo(), mbOrgUserIdcard.getCardType());
                    orgEmployeeVo.setCardNo(encryptStr);
                }
                // 是不是管理员
                GetUserRoleDetailRequest req = new GetUserRoleDetailRequest();
                req.setUid(mbOrgEmployeeInfo.getUid());
                req.setOrgId(mbOrgEmployeeInfo.getOrgId());
                JSONResult<GetUserRoleListResponse> jsonResult = userPermissionService.getRolesByUidAndOrgId(req);
                if (jsonResult.isSUCCESS()) {
                    GetUserRoleListResponse data = jsonResult.getData();
                    List<GetUserRoleListInfo> userRoleListInfoList = data.getUserRoleListInfoList();
                    if (CollUtil.isNotEmpty(userRoleListInfoList)) {
                        orgEmployeeVo.setIsMageger("是");
                    } else {
                        orgEmployeeVo.setIsMageger("否");
                    }
                }
                if (mbOrgEmployeeInfo.getIsLeader() == null || mbOrgEmployeeInfo.getIsLeader() == false) {
                    orgEmployeeVo.setIsCharge("否");
                } else {
                    orgEmployeeVo.setIsCharge("是");
                }
                if (mbOrgInfo != null) {
                    orgEmployeeVo.setCompanyName(mbOrgInfo.getName());
                }
                UserOrgRelationStatusEnum byCode = UserOrgRelationStatusEnum.getByCode(mbOrgEmployeeInfo.getStatus() == null ? 1 : mbOrgEmployeeInfo.getStatus());
                orgEmployeeVo.setStatus(byCode.getDesc());
                MbPostInfo mbPostInfo = postService.find(mbOrgEmployeeInfo.getPostId());
                if (mbPostInfo != null) {
                    orgEmployeeVo.setRank(mbPostInfo.getName());
                }
                MbUserOrgRelation mbRelation = userOrgRelationService.find(orgId, uid);
                // 职级
                if (mbRelation != null) {
                    Long postId = mbRelation.getPostId();
                    if (postId != null) {
                        mbPostInfo = postService.find(postId);
                        orgPostLogVo.setRank(mbPostInfo.getName());
                    }
                }
                orgPostLogList.add(orgEmployeeVo);
            }
        }
        return orgPostLogList;
    }

    private EmployeeInfoResponseBo toEmployeeInfo(MbOrgEmployeeInfo orgEmployeeInfo) {
        EmployeeInfoResponseBo employeeInfoResponseBo = new EmployeeInfoResponseBo();
        BeanUtils.copyProperties(orgEmployeeInfo, employeeInfoResponseBo);
        return employeeInfoResponseBo;
    }

    @Override
    public List<EmployeeInfoResponseBo> listEmployeeInfo(List<OrgUserInfoPk> pkList) {
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = userOrgRelationService.listByPk(pkList);
        return orgEmployeeInfoList.stream().map(this::toEmployeeInfo).collect(Collectors.toList());
    }

    @Override
    public MbOrgEmployeeInfo findByUid(String uid) {
        if(StringUtils.isBlank(uid)){
            return null;
        }
        MbOrgEmployeeInfo employeeInfo = findAllByUid(uid.trim());
        return (employeeInfo == null || employeeInfo.getIsBackground()) ? null : employeeInfo;
    }

    @Override
    public MbOrgEmployeeInfo findAllByUid(String uid) {

        if (StringUtils.isEmpty(uid)) {
            return null;
        }

        MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
        selectParam.setUid(uid.trim());
        selectParam.setDeleteTime(new Date(0));
        return orgEmployeeMapper.selectOne(selectParam);
    }

    @Override
    public MbOrgEmployeeInfo findByMobilePhone(String areaCode, String phoneNum) {

        if (StringUtils.isEmpty(phoneNum) || StringUtils.isEmpty(areaCode)) {
            return null;
        }

        if (!areaCode.contains("+")) {
            areaCode = "+" + areaCode;
        }
        MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
        selectParam.setMobilePhone(phoneNum);
        selectParam.setAreaCode(areaCode);
        selectParam.setDeleteTime(new Date(0));
        return orgEmployeeMapper.selectOne(selectParam);
    }

//    @Override
//    public List<MbOrgEmployeeInfo> batchFindAllByOrgIds(List<String> orgIds, Integer pageNum, Integer pageSize) {
//        // 分页
//        PageHelper.startPage(pageNum, pageSize);
//        // 查询所有用户信息
//        System.out.println(orgIds);
//        List<MbOrgEmployeeInfo> list = mbOrgEmployeeMapper.listByOrgIds(orgIds);
//        return list;
//    }

//    @Override
//    public List<MbOrgEmployeeInfo> batchFindAllBackgroundByOrgIds(List<String> orgIds, Integer pageNum, Integer pageSize) {
//        // 分页
//        PageHelper.startPage(pageNum, pageSize);
//        // 查询所有用户信息
//        System.out.println(orgIds);
//        List<MbOrgEmployeeInfo> list = mbOrgEmployeeMapper.batchSelectAllBackgroundByOrgIds(orgIds);
//        return list;
//    }

//    @Override
//    public List<MbOrgEmployeeInfo> listPageByOrgIdsAndName(List<String> orgIds, String name, Integer pageNum, Integer pageSize) {
//        // 分页
//        PageHelper.startPage(pageNum, pageSize);
//        // 查询所有用户信息
//        List<MbOrgEmployeeInfo> list = mbOrgEmployeeMapper.fuzzyByNameAndOrgIds(orgIds, name);
//        return list;
//    }

//    /**
//     * 模糊搜索员工
//     *
//     * @param request
//     * @return
//     */
//    @Override
//    public List<SearchEmployeeInfo> searchEmployeeInfoList(SearchEmployeeInfoRequest request) {
//        List<String> orgIds = orgInfoSrv.listRecentCompanyDirectDepartmentByOrgId(request.getOrgId());
//        orgIds.add(request.getOrgId());
//        if (orgIds == null || orgIds.size() == 0) {
//            return null;
//        }
//        List<MbOrgEmployeeInfo> mbOrgEmployeeInfos = mbOrgEmployeeMapper.searchEmployeeInfoList(orgIds, request.getKey());
//
//        return CommonUtil.copyList(mbOrgEmployeeInfos, SearchEmployeeInfo.class);
//    }

    @Override
    public List<MbOrgEmployeeInfo> listPageByPostId(Long postId, Integer pageNum, Integer pageSize) {
        PageContext.startPage(pageNum, pageSize);
        List<MbOrgEmployeeInfo> select = orgEmployeeMapper.listByPostIdDesc(postId);
        return select;
    }

    @Override
    public List<MbOrgEmployeeInfo> listPageByPostIdOrUid(Long postId, Integer pageNum, Integer pageSize, String uid,List<String> orgIds) {
        PageHelper.startPage(pageNum, pageSize);
        List<MbOrgEmployeeInfo> select = orgEmployeeMapper.listPageByPostIdOrUid(postId, uid,orgIds);
        return select;
    }

    @Override
    public List<MbOrgEmployeeInfo> listAllByDepartmentIdAndName(String departmentId, String name) {
        return this.listByNameAndOrgId(name, departmentId);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByName(String name) {
        List<String> uids = this.fuzzyByName(name);
        if (CollectionUtils.isEmpty(uids)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByUids(uids);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByNameAllPlat(String name) {
        List<String> uids = this.fuzzyByNameAllPlat(name);
        if (CollectionUtils.isEmpty(uids)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByUids(uids);
    }

    public List<String> fuzzyByNameAllPlat(String name) {
        List<MbOrgEmployeeInfo> list = orgEmployeeMapper.findAllNameAllPlat();
        return list.stream().filter(e -> StringUtils.contains(e.getName(), name)).map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
    }

    public List<String> fuzzyByName(String name) {
        List<MbOrgEmployeeInfo> list = orgEmployeeMapper.findAllName();
        return list.stream().filter(e -> StringUtils.contains(e.getName(), name)).map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
    }

    @Override
    public List<MbOrgEmployeeInfo> listByPostId(Long postId) {
        return orgEmployeeMapper.listByPostId(postId);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByPostIdOrUid(Long postId, String uid) {
        return orgEmployeeMapper.listByPostIdOrUid(postId, uid);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByNameAndOrgId(String name, String orgId) {
        List<String> uids = this.findByOrgId(orgId);
        if (CollectionUtils.isEmpty(uids)) {
            return new ArrayList<>();
        }
        List<MbUserOrgRelation> userOrgRelationList = userOrgRelationMapper.listByOrgIds(Lists.newArrayList(orgId));
        Map<String, MbUserOrgRelation> orgRelationMap = userOrgRelationList.stream().collect(Collectors.toMap(MbUserOrgRelation::getUid, e -> e, (e1, e2) -> e1));
        List<MbOrgEmployeeInfo> orgEmployeeInfoList = orgEmployeeMapper.listByUids(uids);
        return orgEmployeeInfoList.stream().filter(e -> StringUtils.isBlank(name) || StringUtils.contains(e.getName(), name)).peek(e -> {
            MbUserOrgRelation orgRelation = orgRelationMap.get(e.getUid());
            if (orgRelation != null) {
                e.setPostId(orgRelation.getPostId());
                e.setOrgId(orgRelation.getOrgId());
            }
        }).collect(Collectors.toList());
    }

    public List<String> findByOrgId(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return new ArrayList<>();
        }
        List<MbOrgInfo> orgInfoList = orgInfoMapper.listByOrgIds(Lists.newArrayList(orgId));
        if (CollectionUtils.isEmpty(orgInfoList)) {
            return new ArrayList<>();
        }
        List<MbUserOrgRelation> userOrgRelationList = userOrgRelationMapper.listByOrgIds(Lists.newArrayList(orgId));
        return userOrgRelationList.stream().map(MbUserOrgRelation::getUid).collect(Collectors.toList());
    }

    public Map<String, List<MbUserOrgRelation>> findByOrgIds(List<String> orgIds) {
        if (CollectionUtils.isEmpty(orgIds)) {
            return Collections.emptyMap();
        }
        List<MbOrgInfo> orgInfoList = orgInfoMapper.listByOrgIds(orgIds);
        if (CollectionUtils.isEmpty(orgInfoList)) {
            return Collections.emptyMap();
        }
        return Optional.ofNullable(userOrgRelationMapper.listByOrgIds(orgIds)).orElse(new ArrayList<>()).stream()
                .collect(Collectors.groupingBy(MbUserOrgRelation::getOrgId));
    }

    @Override
    public List<MbOrgEmployeeInfo> listByUids(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByUids(ids);
    }

    @Override
    public List<MbOrgEmployeeInfo> selectByUid(String uid) {
        if (StringUtils.isBlank(uid)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.selectByExample(Example.builder(MbOrgEmployeeInfo.class)
                .andWhere(Sqls.custom().andEqualTo("uid", uid.trim()))
                .build());
    }


    @Override
    public List<MbOrgEmployeeInfo> listByUidsAllPlat(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByUidsAllPlat(ids);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByNameAndOrgIds(String query, List<String> orgIds, Integer status, Integer pageNum, Integer pageSize) {
        List<MbOrgEmployeeInfo> employeeInfoList = orgEmployeeMapper.fuzzyByUidsAndOrgIds(null, orgIds, status);
        employeeInfoList = employeeInfoList.stream().filter(e -> StringUtils.contains(e.getName(), query)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(employeeInfoList)) {
            return new ArrayList<>();
        }
        List<String> uids = employeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        if (pageNum != null && pageSize != null) {
            PageContext.startPage(pageNum, pageSize);
        }
        return orgEmployeeMapper.fuzzyByUidsAndOrgIds(uids, orgIds, status);
    }

    @Override
    public IPage<MbOrgEmployeeInfo> pageByNameAndOrgIds(String query, List<String> orgIds, Integer status,
                                                        Integer pageNum, Integer pageSize) {
        List<MbOrgEmployeeInfo> employeeInfoList = orgEmployeeMapper.fuzzyByUidsAndOrgIds(null, orgIds, status);
        employeeInfoList = employeeInfoList.stream().filter(e -> StringUtils.contains(e.getName(), query))
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(employeeInfoList)) {
            return new Page<>();
        }
        List<String> uids = employeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        return PageContext.startPage(pageNum, pageSize,
                () -> orgEmployeeMapper.fuzzyByUidsAndOrgIds(uids, orgIds, status));
    }

    @Override
    public List<MbOrgEmployeeInfo> listBackUserByUids(List<String> uids) {

        uids = Optional.ofNullable(uids).orElse(new ArrayList<>()).stream().filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(uids)) {
            return null;
        }
        return orgEmployeeMapper.listBackgroundByUids(uids);
    }

    @Override
    public List<MbOrgEmployeeInfo> fuzzyByNameAndTel(String key, Integer page, Integer pageSize, Boolean orgValid) {
        if (page != null && pageSize != null) {
            PageContext.startPage(page, pageSize);
        }

        List<String> orgIds = (List<String>) RequestContext.getCurrentContext().getContextParams(DATA_PERMISSION_ORG_ID_LIST);
        log.info("运营代订 orgIds:{}",orgIds);
        return orgEmployeeMapper.fuzzyByNameAndPhoneAndValid(key, orgValid,orgIds);
    }

    @Override
    public List<MbOrgEmployeeInfo> listUnAuditEmployee(String orgId, Integer pageNum, Integer pageSize) {
        // 分页
        PageContext.startPage(pageNum, pageSize);
        // 查询所有用户信息
        List<MbOrgEmployeeInfo> list = orgEmployeeMapper.listUnAuditEmployee(orgId);
        return list;
    }

//    @Override
//    public List<MbOrgEmployeeInfo> fuzzyUserByUidAndNameInOrgs(String key, List<String> orgIds) {
//        return mbOrgEmployeeMapper.fuzzyBackgroundByUidAndNameAndOrgIDs(key, orgIds);
//    }

    /**
     * 证件号掩码加密
     *
     * @param cardNo   证件号
     * @param cardType 证件类型
     * @return
     */
    private static String encryptCardNo(String cardNo, Integer cardType) {
        if (cardType == null || StrUtil.isEmpty(cardNo)) {
            return null;
        }
        if (cardType.equals(CardTypeEnum.ID_CARD.getCode())) {
            return idMask(cardNo, 4, 3);
        }
        if (cardNo.length() < 3) {
            return cardNo;
        }
        return idMask(cardNo, new BigDecimal(cardNo.length()).divide(new BigDecimal(3), 0, BigDecimal.ROUND_HALF_UP).intValue(), 2);
    }

    private void validate(OrgEmployeeVo vo) {
        if (vo == null) {
            throw new CommonException(10001, "参数不能为空");
        }
        if (StringUtils.isBlank(vo.getUid())) {
            throw new CommonException(10002, "员工用户id不能为空");
        }
        if (StringUtils.isBlank(vo.getName())) {
            throw new CommonException(10003, "员工用户姓名不能为空");
        }
        if (vo.getValid() == null) {
            throw new CommonException(10004, "员工用户状态不能为空");
        }
    }


    @Override
    public boolean save(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        return orgEmployeeMapper.insertSelective(mbOrgEmployeeInfo) > 0;

    }

    @Override
    public boolean create(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        int result = orgEmployeeMapper.insertSelective(mbOrgEmployeeInfo);
//        insertOperateLog(mbOrgEmployeeInfo);
        return result > 0;
    }

    @Override
    public boolean update(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        if (mbOrgEmployeeInfo == null || StringUtils.isEmpty(mbOrgEmployeeInfo.getUid())) {
            return false;
        }
        try {
            // 主键补充
            if (mbOrgEmployeeInfo.getId() == null) {
                MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
                selectParam.setUid(mbOrgEmployeeInfo.getUid());
                selectParam.setDeleteTime(new Date(0));
                MbOrgEmployeeInfo oldValue = orgEmployeeMapper.selectOne(selectParam);
                if (oldValue == null || oldValue.getId() == null) {
                    return false;
                }
                mbOrgEmployeeInfo.setId(oldValue.getId());
            }
            mbOrgEmployeeInfo.setDeleteTime(null);
            return updateByPrimaryKeySelective(mbOrgEmployeeInfo) > 0;
        } catch (Exception e) {
            log.error("更新操作获取oldValue失败，OrganizationEmployeeServiceImpl.update:{}", e.getMessage(), e);
            return false;
        }
    }

    @InfoChange(group = "VALID_STAFF", identityExpression = "uid", clientMappingKeyExpressions = "mobilePhone")
    private int updateByPrimaryKeySelective(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        if(StringUtils.isBlank(mbOrgEmployeeInfo.getUid())){
            return 0;
        }
        return orgEmployeeMapper.updateByPrimaryKeySelective(mbOrgEmployeeInfo);
    }

    @Override
    public boolean updateAll(MbOrgEmployeeInfo mbOrgEmployeeInfo) {
        if(StringUtils.isBlank(mbOrgEmployeeInfo.getUid())){
            return false;
        }
        int result = orgEmployeeMapper.updateEmployeeByUid(mbOrgEmployeeInfo);
        return result > 0;
    }

//    @Override
//    public boolean clearPostEmployeeByPostId(Long postId) {
//        int i = mbOrgEmployeeMapper.clearPostEmployeeByPostId(postId);
//        deleteOperateLog(String.valueOf(postId));
//        return i > 0;
//    }

    @Override
    public boolean frontBatchUpdateEmployeePost(List<String> uidList, Long postId, String orgId) {
        return userOrgRelationService.batchUpdatePostByUidAndOrgId(postId, uidList, orgId);
    }

    @Override
    public boolean addEmployeesPosition(List<SubmitSelectEmpVo> empVos, Long postId) {
        boolean flag = true;
        for (SubmitSelectEmpVo empVo : empVos) {
            flag = userOrgRelationService.setPostIdByUidAndOrgId(empVo.getId(), empVo.getOrgId(), postId);
        }
        return flag;
    }

    @Override
    public boolean isBackgroundUser(String uid) {
        MbOrgEmployeeInfo mbOrgEmployeeInfo = findByUid(uid);
        if (mbOrgEmployeeInfo != null && mbOrgEmployeeInfo.getIsBackground() != null) {
            return mbOrgEmployeeInfo.getIsBackground();
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean clearEmployeesPosition(List<SubmitSelectEmpVo> submitSelectEmpVos) {
        boolean flag = true;
//        StringBuilder ids = new StringBuilder();

        try {
            Map<String, String> orgNameMap;
            MbUserOrgRelation mbUserOrgRelation;
            List<MbOrgInfo> mbOrgInfoList;
            MbPostInfo mbPostInfo;
            List<EmployeeOpratLogVo> employeeOpratLogVoList = Lists.newArrayList();
            List<MbOrgEmployeeInfo> list;
            List<String> orgIds;
            EmployeeOpratLogVo employeeOpratLogVo = null;
            Long postId = null;
            for (SubmitSelectEmpVo submitSelectVo : submitSelectEmpVos) {
                mbUserOrgRelation = userOrgRelationService.find(submitSelectVo.getOrgId(), submitSelectVo.getId());
                postId = mbUserOrgRelation.getPostId();
                // 查询岗位信息
                mbPostInfo = postService.find(postId);
                if (mbPostInfo != null) {
                    // #1.查询岗位下人员列表
                    list = listByPostId(postId);
                    orgIds = list.stream().map(MbOrgEmployeeInfo::getOrgId).distinct().collect(Collectors.toList());
                    // #2.查询组织结构名称
                    mbOrgInfoList = organizationInfoService.listNameByOrgIds(orgIds);
                    if (CollectionUtils.isEmpty(mbOrgInfoList)) {
                        return flag;
                    }
                    // key:orgId , value:name
                    orgNameMap = mbOrgInfoList.stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, MbOrgInfo::getName));
                    if (!CollectionUtils.isEmpty(list)) {
                        for (MbOrgEmployeeInfo mbOrgEmployeeInfo : list) {
                            if (mbOrgEmployeeInfo.getUid().equals(submitSelectVo.getId())) {
                                employeeOpratLogVo = new EmployeeOpratLogVo();
                                employeeOpratLogVo.setPostName(mbPostInfo.getName());
                                employeeOpratLogVo.setUId(mbOrgEmployeeInfo.getUid());
                                employeeOpratLogVo.setDepartment(orgNameMap.get(mbOrgEmployeeInfo.getOrgId()));
                                employeeOpratLogVo.setName(mbOrgEmployeeInfo.getName());
                                employeeOpratLogVo.setPhone(mbOrgEmployeeInfo.getMobilePhone());
                                employeeOpratLogVo.setOrgId(mbOrgEmployeeInfo.getOrgId());
                                employeeOpratLogVo.setId(postId);
                                employeeOpratLogVo.setAllowance(String.valueOf(mbPostInfo.getAllowance().setScale(2, RoundingMode.HALF_UP)));
                                employeeOpratLogVoList.add(employeeOpratLogVo);
                            }
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(employeeOpratLogVoList)) {
                for (EmployeeOpratLogVo opratLogVo : employeeOpratLogVoList) {
                    List<OperateLogContentDataVo> operateLogContentDataVos = OperateLogContentUtil.deleteToContent(opratLogVo, new EmployeeOpratLogVo());
                    deleteOperateLog(String.valueOf(postId), operateLogContentDataVos);
                }
            }
        } catch (Exception e) {
            log.error("移除员工异常，异常原因:{}", e.getMessage(), e);
        }
        for (SubmitSelectEmpVo submitSelectEmpVo : submitSelectEmpVos) {
            flag = userOrgRelationService.cleanPostIdByUidAndOrgId(submitSelectEmpVo.getId(), submitSelectEmpVo.getOrgId());
//            ids.append(submitSelectEmpVo.getId());
//            ids.append(",");
        }


//        deleteOperateLog(ids.toString());
        return flag;
    }

    @Override
    public boolean deleteByUid(String uid) {
        int i = orgEmployeeMapper.deleteByUid(uid);
        deleteOperateLog(uid);
        return i > 0;
    }

    @InfoChange(group = "VALID_STAFF", identityExpression = "uid", clientMappingKeyExpressions = "mobilePhone")
    @Override
    public Integer updateEmployeeSelective(MbOrgEmployeeInfo employee) {

        return orgEmployeeMapper.updateByPrimaryKeySelective(employee);
    }

    /**
     * 新增员工
     *
     * @param employee
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public ServiceErrorEnum addEmployee(MbOrgEmployeeInfo employee, List<MbOrgUserIdcard> cardTypes, List<MbOrgUserFfpinfo> ffps, List<MbUserOrgRelation> orgRelations) {

        try {
            if (employee == null || StringUtils.isEmpty(employee.getAreaCode())
                    || StringUtils.isEmpty(employee.getMobilePhone()) || StringUtils.isEmpty(employee.getName())
                    || CollectionUtils.isEmpty(orgRelations)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_NULL);
            }

            // 1）新增员工
            if (findAllByUid(employee.getUid()) != null) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_ALREADY_EXISTS);
            }

            MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
            record.setIsBackground(false);
            record.setMobilePhone(employee.getMobilePhone());
            record.setAreaCode(employee.getAreaCode());
            record.setDeleteTime(new Date(0));
            MbOrgEmployeeInfo oldEmployeeInfo = mbOrgEmployeeLoader.selectOneByRecord(record);
            if (oldEmployeeInfo != null) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST);
            }
            employee.setUid(Optional.ofNullable(employee.getUid()).orElse(UUID.randomUUID().toString()));
            if (!create(employee)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_CREATE_ERROR);
            }
            // 绑定兑换码
            redemptionCodeService.bindRedemptionCode(employee.getUid(), employee.getName());

            MbUserLogin userLogin = userLoginService.findByPhone(employee.getAreaCode(), employee.getMobilePhone());
            // 相同手机号、不同UID，则新增失败
            if (userLogin != null && !employee.getUid().equals(userLogin.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST);
            }
            // 相同手机号、相同UID，则删除登录信息，后续重新添加
            else if (userLogin != null) {
                userLoginService.deleteByUid(employee.getUid());
            }

            // 2）新增登录信息
            MbUserLogin addUserLogin = new MbUserLogin();
            addUserLogin.setAccountName(employee.getAreaCode() + employee.getMobilePhone());
            addUserLogin.setUid(employee.getUid());
            addUserLogin.setPwd(Md5Util.getDeepMd5Msg(employee.getUid(), employee.getPwd()));
            addUserLogin.setUserName(employee.getName());
            addUserLogin.setBgUser(0);
            addUserLogin.setCountryCode(employee.getAreaCode());
            addUserLogin.setPhoneNum(employee.getMobilePhone());
            addUserLogin.setEmail(employee.getEmail());
            addUserLogin.setStatus(1);
            if (!userLoginService.create(addUserLogin)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.ACCOUNT_CREATE_ERROR);
            }

            // 3）先删后增身份
            userOrgRelationService.deleteByUid(employee.getUid());
            if (!userOrgRelationService.batchSave(orgRelations)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_CREATE_ERROR);
            }

            // 4）先删后增用户新鲜度数据
            freshPassengerService.deleteEmployee(employee.getUid(), null);
            List<MbFreshPassenger> fpList = orgRelations.stream().filter(Objects::nonNull).map(org -> {
                MbFreshPassenger temp = new MbFreshPassenger();
                temp.setEmployeeUid(employee.getUid());
                temp.setOrgId(org.getOrgId());
                temp.setName(employee.getName());
                String enName = "";
                if (StringUtils.isNotBlank(employee.getFirstEnName()) || StringUtils.isNotBlank(employee.getLastEnName())) {
                    enName = (StringUtils.isNotBlank(employee.getFirstEnName()) ? employee.getFirstEnName() : "") + "/" + (StringUtils.isNotBlank(employee.getLastEnName()) ? employee.getLastEnName() : "");
                }
                temp.setEnName(StringUtils.isEmpty(enName) ? null : enName);
                temp.setValid(false);
                temp.setIsDeleted(false);
                return temp;
            }).collect(Collectors.toList());
            if (!freshPassengerService.batchSave(fpList)) {
                throw new CorpBusinessException(ExceptionCodeEnum.Alert, "新增员工常旅客失败");
            }
            List<MbFreshPassengerRelation> fprList = fpList.stream().map(e -> {
                MbFreshPassengerRelation mbFreshPassengerRelation = new MbFreshPassengerRelation();
                mbFreshPassengerRelation.setEmployeeFlag(1);
                mbFreshPassengerRelation.setFreshUid(e.getEmployeeUid());
                mbFreshPassengerRelation.setFreshTime(new Date());
                mbFreshPassengerRelation.setIsDeleted(false);
                mbFreshPassengerRelation.setUid(e.getEmployeeUid());
                mbFreshPassengerRelation.setDatachangeLasttime(new Date());
                mbFreshPassengerRelation.setDatachangeCreatetime(new Date());
                return mbFreshPassengerRelation;
            }).collect(Collectors.toList());
            freshPassengerRelationService.save(fprList);
            // 5）新增用户职级信息
            saveCardTypeAndFfp(employee.getUid(), cardTypes, ffps);
            //可能账号以前存在 删除禁用设置
            tokenValidUtil.updateTokenValid(employee.getUid(), true);

            return ServiceErrorEnum.Success;
        } catch (Exception e) {
            log.info("异常信息：{}", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            ServiceErrorEnum customError = ServiceErrorEnum.CUSTOM_ERROR;
            if (StringUtils.isNotBlank(e.getMessage())) {
                customError.setErrorMessage(e.getMessage());
            }
            return customError;
        }
    }

    /**
     * 修改员工
     *
     * @param employee
     * @param cardTypes
     * @param ffps
     * @param orgRelations
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public ServiceErrorEnum updateEmployee(MbOrgEmployeeInfo employee, List<MbOrgUserIdcard> cardTypes, List<MbOrgUserFfpinfo> ffps, List<MbUserOrgRelation> orgRelations) {

        try {
            if (employee == null || StringUtils.isEmpty(employee.getAreaCode())
                    || StringUtils.isEmpty(employee.getMobilePhone()) || StringUtils.isEmpty(employee.getName())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_NULL);
            }

            // 1）修改员工
            String uid = employee.getUid();
            MbOrgEmployeeInfo existEmp = findByUid(uid);
            if (existEmp == null || existEmp.getId() == null || !uid.equalsIgnoreCase(existEmp.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_INFO_DONT_EXISTS);
            }
            MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
            record.setAreaCode(employee.getAreaCode());
            record.setMobilePhone(employee.getMobilePhone());
            record.setIsBackground(false);
            MbOrgEmployeeInfo existEmpOfPhone = mbOrgEmployeeLoader.selectOneByRecord(record);
            if (existEmpOfPhone != null && !uid.equals(existEmpOfPhone.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST);
            }
            employee.setId(existEmp.getId());
            if (!update(employee)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_CREATE_ERROR);
            }
            Long result = employee.getId();


            // 2）修改登录信息
            MbUserLogin existLogin = userLoginService.getByUid(uid);
            if (existLogin == null || existLogin.getId() == null || !uid.equalsIgnoreCase(existLogin.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_INFO_NULL);
            }
            MbUserLogin existLoginOfPhone = userLoginService.findByPhone(employee.getAreaCode(), employee.getMobilePhone());
            // 相同手机号、不同UID，则新增失败
            if (existLoginOfPhone != null && !uid.equals(existLoginOfPhone.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.EMPLOYEE_PHONE_NO_EXIST);
            }

            MbUserLogin updateUserLogin = new MbUserLogin();
            updateUserLogin.setId(existLogin.getId());
            updateUserLogin.setAccountName(employee.getAreaCode() + employee.getMobilePhone());
            if (StringUtils.isNotBlank(employee.getPwd())) {
                updateUserLogin.setPwd(Md5Util.getDeepMd5Msg(uid, employee.getPwd()));
            }
            updateUserLogin.setUserName(employee.getName());
            updateUserLogin.setCountryCode(employee.getAreaCode());
            updateUserLogin.setPhoneNum(employee.getMobilePhone());
            updateUserLogin.setEmail(employee.getEmail());
            if (userLoginService.updateUserLogin(updateUserLogin, false) <= 0) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.ACTION_FAILED);
            }

            // 3）修改用户新鲜度数据
            if (!existEmp.getName().equals(employee.getName())) {

                MbFreshPassenger updatePsgParam = new MbFreshPassenger();
                updatePsgParam.setEmployeeUid(employee.getUid());
                updatePsgParam.setName(employee.getName());
                String enName = "";
                if (StringUtils.isNotBlank(employee.getFirstEnName()) || StringUtils.isNotBlank(employee.getLastEnName())) {
                    enName = (StringUtils.isNotBlank(employee.getFirstEnName()) ? employee.getFirstEnName() : "") + "/" + (StringUtils.isNotBlank(employee.getLastEnName()) ? employee.getLastEnName() : "");
                }
                updatePsgParam.setEnName(enName);
                log.info("更新新鲜度入参：{}", JsonUtils.toJsonString(updatePsgParam));
                if (!freshPassengerService.updateEmployeeOrg(updatePsgParam)) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.ACTION_FRESH_PASSENGER_FAILED);
                }
            }
            // 4) 添加用户身份信息
            List<MbUserOrgRelation> mbUserOrgRelations = userOrgRelationService.listByUid(employee.getUid());
            Map<String, Long> orgIdMaps = mbUserOrgRelations.stream().collect(Collectors.toMap(MbUserOrgRelation::getOrgId, MbUserOrgRelation::getId, (k1, k2) -> k1));
            //新增
            List<MbUserOrgRelation> addDate = Optional.ofNullable(orgRelations).orElse(new ArrayList<>()).stream().filter(e -> orgIdMaps.get(e.getOrgId()) == null).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(addDate)) {
                if (!userOrgRelationService.batchSave(addDate)) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_CREATE_ERROR);
                }
            }
            List<MbUserOrgRelation> updateList = Optional.ofNullable(orgRelations).orElse(new ArrayList<>()).stream().filter(e -> orgIdMaps.get(e.getOrgId()) != null).map(e -> {
                Long id = orgIdMaps.get(e.getOrgId());
                e.setId(id);
                return e;
            }).collect(Collectors.toList());
            //更新
            if (CollectionUtils.isNotEmpty(updateList)) {
                if (updateList.stream().map(x -> userOrgRelationService.update(x)).collect(Collectors.toList()).contains(false)) {
                    throw new CorpBusinessException(ExceptionCodeEnum.Alert, "更新员工身份失败");
                }
            }
            saveCardTypeAndFfp(uid, cardTypes, ffps);

            //可能账号以前存在 删除禁用设置
            tokenValidUtil.updateTokenValid(employee.getUid(), true);

            return ServiceErrorEnum.Success;
        } catch (Exception e) {
            log.info("异常信息：{}", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            ServiceErrorEnum customError = ServiceErrorEnum.CUSTOM_ERROR;
            if (StringUtils.isNotBlank(e.getMessage())) {
                customError.setErrorMessage(e.getMessage());
            }
            return customError;
        }

    }

    /**
     * 保存证件类型和常旅客卡
     *
     * @param uid
     * @param cardTypes
     * @param ffps
     */
    private void saveCardTypeAndFfp(String uid, List<MbOrgUserIdcard> cardTypes, List<MbOrgUserFfpinfo> ffps) {

        // 3）先删后增有效证件
        organizationUserIdCardService.deleteByEmployeeUid(uid);
        if (CollectionUtils.isNotEmpty(cardTypes)) {
            for (MbOrgUserIdcard item : cardTypes) {
                List<MbOrgUserIdcard> cardList = organizationUserIdCardService.findByTypeAndNo(item.getCardType(), item.getCardNo());
                if (CollectionUtils.isNotEmpty(cardList)) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.CARD_EXISTS);
                }
            }
            cardTypes.forEach(card -> {
                List<MbOrgUserIdcard> mbOrgUserIdcards = organizationUserIdCardService.listEmployeeByTypeAndNo(card.getCardType(), card.getCardNo());
                if (!CollectionUtils.isEmpty(mbOrgUserIdcards)) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.CARD_EXISTS);
                }
            });
            boolean flag = organizationUserIdCardService.batchSave(cardTypes);
            if (!flag) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.ACTION_FAILED);
            }
        }

        // 4）先删后增常旅客卡
        organizationUserFfpService.deleteByUid(uid);
        if (CollectionUtils.isNotEmpty(ffps)) {
            if (!organizationUserFfpService.saveList(ffps)) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.ACTION_FRESH_PASSENGER_FAILED);
            }
        }
    }

    /**
     * 删除员工
     *
     * @param employee
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public ServiceErrorEnum deleteEmployee(MbOrgEmployeeInfo employee) {
        log.info("OrganizationEmployeeServiceImpl.deleteEmployee:employee={}", JsonUtils.toJsonString(employee));
        try {
            if (employee == null || StringUtils.isEmpty(employee.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.PARAMS_NULL);
            }


            // 1）删除员工
            if (employee.getId() == null) {
                MbOrgEmployeeInfo empWaitDelete = findAllByUid(employee.getUid());
                if (empWaitDelete == null) {
                    throw new CorpBusinessException(OrganizationResponseCodeEnum.DONT_WAIT_DELETE_EMPLOYEE);
                }
                employee.setId(empWaitDelete.getId());
            }
            if (!deleteByUid(employee.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.DELETE_USER_FAILED);
            }
            Long result = employee.getId();

            // 2）删除登录信息
            if (!userLoginService.deleteByUid(employee.getUid())) {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.DELETE_USER_FAILED);
            }

            // 3）删除身份
            userOrgRelationService.deleteByUid(employee.getUid());


            // 4）删除有效证件
            organizationUserIdCardService.deleteByEmployeeUid(employee.getUid());


            // 5）删除常旅客卡
            organizationUserFfpService.deleteByUid(employee.getUid());


            // 6）删除用户新鲜度数据
            freshPassengerService.deleteEmployee(employee.getUid(), null);

            //可能账号以前存在 删除禁用设置
            tokenValidUtil.updateTokenValid(employee.getUid(), false);
            return ServiceErrorEnum.Success;
        } catch (Exception e) {
            log.info("异常信息：{}", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            ServiceErrorEnum customError = ServiceErrorEnum.CUSTOM_ERROR;
            if (StringUtils.isNotBlank(e.getMessage())) {
                customError.setErrorMessage(e.getMessage());
            }
            return customError;
        }
    }

    @Override
    public List<MbOrgEmployeeInfo> listByPostIds(List<Long> postIds) {
        if (CollectionUtils.isEmpty(postIds)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByPostIds(postIds);
    }

    @Override
    public List<MbOrgEmployeeInfo> listByRoleIds(List<Long> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return new ArrayList<>();
        }
        return orgEmployeeMapper.listByRoleIds(roleIds);
    }

    @Override
    public List<MbOrgEmployeeInfo> findBgUserByName(String name) {
        MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
        selectParam.setDeleteTime(new Date(0));
        selectParam.setIsBackground(true);
        List<MbOrgEmployeeInfo> employeeInfoList = orgEmployeeMapper.select(selectParam);
        log.info("findBgUserByName:{}", JsonUtils.toJsonString(employeeInfoList));
        return employeeInfoList.stream().filter(e -> StringUtils.contains(e.getName(), name)).collect(Collectors.toList());
    }

    @Override
    public List<MbOrgEmployeeInfo> findLikeName(String name) {
        MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
        selectParam.setDeleteTime(new Date(0));

        if (Config.defaultConfig().enabledQuery()) {
            // 按名称模糊查询
            log.info("模糊查询组件执行");
            if (StringUtils.isBlank(name)) {
                return orgEmployeeMapper.select(selectParam);
            }
            MbOrgEmployeeInfo nameCondition = new MbOrgEmployeeInfo();
            nameCondition.setName(name);
            return orgEmployeeMapper.fuzzyByNameSecurity(nameCondition);
        }

        List<MbOrgEmployeeInfo> employeeInfoList = orgEmployeeMapper.select(selectParam);
        if (StringUtils.isBlank(name)) {
            return employeeInfoList;
        }
        return employeeInfoList.stream().filter(e -> StringUtils.contains(e.getName(), name)).collect(Collectors.toList());
    }

    @Override
    public List<MbOrgEmployeeInfo> findLikeName(List<String> orgIds, String name) {
        Example example = new Example(MbUserOrgRelation.class);
        example.createCriteria().andIn("orgId", orgIds).andIsNotNull("postId");

        List<MbUserOrgRelation> mbUserOrgRelations = userOrgRelationMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(mbUserOrgRelations)) {
            return Lists.newArrayList();
        }

        List<String> collect = mbUserOrgRelations.stream().map(MbUserOrgRelation::getUid).collect(Collectors.toList());

        Example userExample = new Example(MbOrgEmployeeInfo.class);
        userExample.createCriteria().andEqualTo("deleteTime", new Date(0)).andIn("uid", collect);
        List<MbOrgEmployeeInfo> employeeInfoList = orgEmployeeMapper.selectByExample(userExample);
        if (StringUtils.isBlank(name)) {
            return employeeInfoList;
        }
        return employeeInfoList.stream().filter(e -> StringUtils.contains(e.getName(), name)).collect(Collectors.toList());
    }

    @Override
    public List<MbOrgEmployeeInfo> findByName(String name) {
        MbOrgEmployeeInfo selectParam = new MbOrgEmployeeInfo();
        selectParam.setDeleteTime(new Date(0));
        selectParam.setName(name);
        return orgEmployeeMapper.select(selectParam);
    }

    @Override
    public OrgEmployeeVo searchEmployeeInfo(SearchEmployeeInfoRequestBO request) {
        String uid = request.getUid();
        String orgId = request.getOrgId();
        if (StringUtils.isBlank(uid)) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.UID_NULL);
        }
        // 查询用户信息
        MbOrgEmployeeInfo mbOrgEmployeeInfo = this.findByUid(uid);
        if (mbOrgEmployeeInfo == null) {
            throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_INFO_DONT_EXISTS);
        }
        // 是否读取nameInfo的数据,T:读取  F:不读取
        boolean nameInfoReadSwitch = "T".equalsIgnoreCase(organizationApollo.getNameInfoReadSwitch());
        OrgEmployeeVo orgEmployeeVo = new OrgEmployeeVo();
        if(nameInfoReadSwitch && StrUtil.isNotBlank(mbOrgEmployeeInfo.getNameInfo())){
            NameInfoBo nameInfoBo = JsonUtils.parse(mbOrgEmployeeInfo.getNameInfo(), NameInfoBo.class);
            orgEmployeeVo.setSurname(nameInfoBo.getSurname());
            orgEmployeeVo.setGivenname(nameInfoBo.getGivenname());
            orgEmployeeVo.setFullEnName(com.corpgovernment.organization.util.StrUtils.processFullEnName(nameInfoBo.getSurname(),nameInfoBo.getGivenname()));
            orgEmployeeVo.setFullName(nameInfoBo.getFullName());
            orgEmployeeVo.setNationality(nameInfoBo.getNationality());
        }else{
            orgEmployeeVo.setSurname(mbOrgEmployeeInfo.getLastEnName());
            orgEmployeeVo.setGivenname(mbOrgEmployeeInfo.getFirstEnName());
            orgEmployeeVo.setFullEnName(com.corpgovernment.organization.util.StrUtils.processFullEnName(mbOrgEmployeeInfo.getLastEnName(),mbOrgEmployeeInfo.getFirstEnName()));
            orgEmployeeVo.setFullName(mbOrgEmployeeInfo.getName());
            orgEmployeeVo.setNationality(mbOrgEmployeeInfo.getNationality());
        }
        BeanUtils.copyProperties(mbOrgEmployeeInfo, orgEmployeeVo);
        orgEmployeeVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
        orgEmployeeVo.setBirthday(DateUtil.format(mbOrgEmployeeInfo.getBirthday(), "yyyy-MM-dd"));
        // 查询用户身份信息
        MbUserOrgRelation mbUserOrgRelation = userOrgRelationService.find(orgId, uid);
        if (mbUserOrgRelation == null) {
            //部门转移问题，目前系统已经移除多身份用uid查询也应该只有一条
            List<MbUserOrgRelation> mbUserOrgRelationList = userOrgRelationService.findByUid(uid);
            if (CollectionUtils.isNotEmpty(mbUserOrgRelationList)){
                mbUserOrgRelation = mbUserOrgRelationList.get(0);
            } else {
                throw new CorpBusinessException(OrganizationResponseCodeEnum.USER_INFO_DONT_EXISTS);
            }
        }
        BeanUtils.copyProperties(mbUserOrgRelation, orgEmployeeVo);
        // orgId查找orgname
        if (orgEmployeeVo.getOrgId() != null) {
            MbOrgInfo mbOrgInfo = organizationInfoService.findByOrgId(orgEmployeeVo.getOrgId());
            if (mbOrgInfo != null) {
                orgEmployeeVo.setOrgName(mbOrgInfo.getName());
            }
        }
        // 封装末级子公司id
        MbOrgInfo mbOrgInfo = organizationInfoService.findRecentCompanyIdByOrgId(orgId);
        if (mbOrgInfo != null) {
            orgEmployeeVo.setRecentCompanyId(mbOrgInfo.getOrgId());
            orgEmployeeVo.setRecentCompanyName(mbOrgInfo.getName());
        }
        return orgEmployeeVo;
    }

    @Override
    public List<OrgEmployeeVo> findOrgInfoByUid(String uid) {
        if(StringUtils.isBlank(uid)){
            return null;
        }
        // 查询用户身份信息
        List<MbUserOrgRelation> userOrgRelationList = userOrgRelationService.findByUid(uid);
        if (CollectionUtils.isEmpty(userOrgRelationList) || userOrgRelationList.size() == 0) {
            return null;
        }
        List<OrgEmployeeVo> result = new ArrayList<>();
        userOrgRelationList.forEach(item -> {
            MbOrgInfo orgInfo = organizationInfoService.findByOrgId(item.getOrgId());
            OrgEmployeeVo orgEmployeeVo = new OrgEmployeeVo();
            orgEmployeeVo.setOrgId(orgInfo.getOrgId());
            orgEmployeeVo.setOrgName(orgInfo.getName());
            orgEmployeeVo.setOrgType(orgInfo.getOrgType());
            result.add(orgEmployeeVo);

            if (OrgTypeEnum.D.getCode().equals(orgInfo.getOrgType())) {
                MbOrgInfo corpOrgInfo = organizationInfoService.findRecentCompanyIdByOrgId(item.getOrgId());
                OrgEmployeeVo corpEmployeeVo = new OrgEmployeeVo();
                corpEmployeeVo.setOrgId(corpOrgInfo.getOrgId());
                corpEmployeeVo.setOrgName(corpOrgInfo.getName());
                corpEmployeeVo.setOrgType(corpOrgInfo.getOrgType());
                result.add(corpEmployeeVo);
            }

        });
        return result;
    }

    @Override
    public List<SearchCorpEmpResponse> selectEmployeeByOrgIds(List<String> orgIds) {
        List<MbOrgEmployeeInfo> mbOrgEmployeeInfos = orgEmployeeMapper.selectByOrgIds(orgIds);
        List<SearchCorpEmpResponse> result = new ArrayList<>();
        mbOrgEmployeeInfos.forEach(item -> {
            SearchCorpEmpResponse vo = new SearchCorpEmpResponse();
            vo.setUid(item.getUid());
            vo.setName(item.getName());
            vo.setMobilePhone(item.getMobilePhone());
            vo.setOrgId(item.getOrgId());
            vo.setOrgName(item.getOrgName());
            vo.setEmail(item.getEmail());
            result.add(vo);
        });
        return result;
    }

    @Override
    public List<EmployeeOrgVo> findEmployeeInfoByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)){
            return Collections.emptyList();
        }
        List<EmployeeOrgVo> employeeOrgVos = new ArrayList<>();
        List<MbOrgEmployeeInfo> employeeInfos = orgEmployeeMapper.listByUidsAllPlat(ids);
        if (CollectionUtils.isEmpty(employeeInfos)) {
            return employeeOrgVos;
        }
        Map<String, MbOrgEmployeeInfo> employeeInfoMap = employeeInfos.stream().collect(Collectors.toMap(MbOrgEmployeeInfo::getUid, mbOrgEmployeeInfo -> mbOrgEmployeeInfo));
        List<MbUserOrgRelation> mbUserOrgRelations = userOrgRelationMapper.listByUids(ids);
        if (CollectionUtils.isEmpty(mbUserOrgRelations)) {
            return employeeOrgVos;
        }

        for (MbUserOrgRelation mbUserOrgRelation : mbUserOrgRelations) {
            MbOrgEmployeeInfo mbOrgEmployeeInfo = employeeInfoMap.get(mbUserOrgRelation.getUid());
            EmployeeOrgVo employeeOrgVo = new EmployeeOrgVo();
            employeeOrgVo.setUid(mbUserOrgRelation.getUid());
            employeeOrgVo.setUname(mbOrgEmployeeInfo.getName());
            employeeOrgVo.setEmployeeType(mbOrgEmployeeInfo.getEmployeeType());
            String orgId = mbUserOrgRelation.getOrgId();
            employeeOrgVo.setOrgId(orgId);
            MbOrgInfo mbOrgInfo = organizationInfoService.findRecentCompanyIdByOrgId(orgId);
            if (Objects.nonNull(mbOrgInfo)) {
                employeeOrgVo.setCorpId(mbOrgInfo.getOrgId());
            } else {
                employeeOrgVo.setCorpId(orgId);
            }
            employeeOrgVo.setMobilePhone(mbOrgEmployeeInfo.getMobilePhone());
            employeeOrgVo.setAreaCode(mbOrgEmployeeInfo.getAreaCode());
            employeeOrgVo.setGender(mbOrgEmployeeInfo.getGender());
            employeeOrgVo.setEmail(mbOrgEmployeeInfo.getEmail());
            employeeOrgVos.add(employeeOrgVo);
        }

        return employeeOrgVos;
    }

    @Override
    public QueryEmployeeResponse queryEmployeeList(QueryEmployeeRequest request) {
        if (CollectionUtils.isEmpty(request.getUidList())) {
            return new QueryEmployeeResponse();
        }

        List<String> orgIdList = request.getUidList().stream().distinct().collect(Collectors.toList());
        List<MbOrgEmployeeInfo> dbEmployeeList = orgEmployeeMapper.listByUidsAllPlat(orgIdList);
        List<EmployeeDTO> employeeList = dbEmployeeList.stream().map(e -> {
            EmployeeDTO employee = new EmployeeDTO();
            employee.setUid(e.getUid());
            employee.setName(e.getName());
            return employee;
        }).collect(Collectors.toList());

        QueryEmployeeResponse response = new QueryEmployeeResponse();
        response.setEmployeeList(employeeList);
        return response;
    }

    @Override
    public SearchCorpEmpResponse findEmpAndOrgByUid(String uid) {
        if(StringUtils.isBlank(uid)){
            return null;
        }
        MbOrgEmployeeInfo mbOrgEmployeeInfos = orgEmployeeMapper.findEmpAndOrgByUid(uid.trim());
        if(ObjectUtil.isEmpty(mbOrgEmployeeInfos)){
            return null;
        }
        SearchCorpEmpResponse vo = new SearchCorpEmpResponse();
        vo.setUid(mbOrgEmployeeInfos.getUid());
        vo.setName(mbOrgEmployeeInfos.getName());
        vo.setMobilePhone(mbOrgEmployeeInfos.getMobilePhone());
        vo.setOrgId(mbOrgEmployeeInfos.getOrgId());
        vo.setOrgName(mbOrgEmployeeInfos.getOrgName());
        vo.setAreaCode(mbOrgEmployeeInfos.getAreaCode());
        return vo;
    }

    @Override
    public UpdateEmployeeResponseBO updateByUid(UpdateEmployeeRequestBO request) {
        if (request == null) {
            return UpdateEmployeeResponseBO.create(false);
        }
        MbOrgEmployeeInfo record = new MbOrgEmployeeInfo();
        record.setEmail(request.getEmail());
        record.setUid(request.getUid());
        record.setReconciliationEmail(request.getReconciliationEmail());
        boolean flag = mbOrgEmployeeLoader.updateByUid(record);
        return UpdateEmployeeResponseBO.create(flag);
    }

    @Override
    public List<UserEmailDTO> findUserInfoByOrgIds(List<String> orgId) {
        return orgInfoMapper.findUserInfoByOrgIds(orgId);
    }

    @Override
    public List<MbOrgEmployeeInfo> findUidByOrgId(List<String> orgId) {
        return orgInfoMapper.findUidByOrgId(orgId);
    }

    @Override
    public IPage<MbOrgEmployeeInfo> pageByUidsAndAnyParam(List<String> uidList, String phone, String email,
        Integer pageIndex, Integer pageSize) {
        if (CollectionUtils.isEmpty(uidList)) {
            return new com.ctrip.corp.obt.shard.sql.mybatis.interceptor.pagination.Page<>(pageIndex, pageSize);
        }
        if (StringUtils.isBlank(phone)) {
            phone = null;
        }
        if (StringUtils.isBlank(email)) {
            email = null;
        }

        String finalPhone = phone;
        String finalEmail = email;
        return PageContext.startPage(pageIndex, pageSize,
            () -> orgEmployeeMapper.listAllByUidsAndAnyParam(uidList, finalPhone, finalEmail));
    }

    @Override
    public UpdateEmployeeResponseBO updateEmployeeTypeByUid(Integer employeeType, List<String> ids) {
        if (employeeType == null || Objects.isNull(ids) || ids.size() == 0){
            log.info("员工类型更新请求参数错误");
            return UpdateEmployeeResponseBO.create(false);
        }
        boolean flag = orgEmployeeMapper.updateEmployeeTypeByIds(employeeType, ids) > 0;
        log.info("员工类型更新状态为:{}", JsonUtils.toJsonString(flag));
        return UpdateEmployeeResponseBO.create(flag);
    }

    @Override
    public List<MbOrgEmployeeInfo> findAllBackgroundUsers() {
        MbOrgEmployeeInfo mbOrgEmployeeInfo = new MbOrgEmployeeInfo();
        mbOrgEmployeeInfo.setDeleteTime(new Date(0));
        mbOrgEmployeeInfo.setIsBackground(true);
        mbOrgEmployeeInfo.setValid("T");
        return orgEmployeeMapper.select(mbOrgEmployeeInfo);
    }

    @Override
    public List<MbOrgEmployeeInfo> findManageFuzzy(FindManageFuzzyRequestBO request) {
        String fuzzyQuery = request.getFuzzyQuery();
        if (StringUtils.isBlank(fuzzyQuery)) {
            return null;
        }
        MbOrgEmployeeInfo nameQuery = new MbOrgEmployeeInfo();
        nameQuery.setName(fuzzyQuery);
        nameQuery.setDeleteTime(new Date(0));
        List<MbOrgEmployeeInfo> nameRes = orgEmployeeMapper.select(nameQuery);

        MbOrgEmployeeInfo uidQuery = new MbOrgEmployeeInfo();
        uidQuery.setUid(fuzzyQuery);
        uidQuery.setDeleteTime(new Date(0));
        List<MbOrgEmployeeInfo> uidRes = orgEmployeeMapper.select(uidQuery);

        nameRes.addAll(uidRes);
        return nameRes;
    }

    @Override
    public QueryEmployeeInfoWithPermissionResponse queryEmployeeWithPermission(
        QueryEmployeeInfoWithPermissionRequest request) {
        QueryEmployeeInfoWithPermissionResponse response = new QueryEmployeeInfoWithPermissionResponse();

        // 获取当前登录用户权限下所有orgId
        BaseUserInfo userInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
        Set<String> dataPermissionSet = null;
        // 判断是否是admin用户，如果是，则返回全量数据
        if (Boolean.TRUE.equals(userInfo.getBgUser())) {
            // admin使用else中的方法返回的数据为0
            dataPermissionSet = mbOrgInfoMapper
                .listAll().stream().map(MbOrgInfo::getOrgId).collect(Collectors.toSet());
        } else {
            // 当前登录用户权限下所有orgId
            dataPermissionSet = Optional.ofNullable(DataPermissionsContext.getRoleAllDataPermissions())
                .map(ResourceInfo::getDeptInfos).orElse(new ArrayList<>()).stream().map(ResourceInfo.DeptInfo::getOrgId)
                .collect(Collectors.toSet());
        }
        log.info("当前登录用户权限下可查询orgId为：" + JsonUtils.toJsonString(dataPermissionSet));

        if (CollectionUtils.isEmpty(dataPermissionSet)) {
            return response;
        }

        IPage<MbOrgEmployeeInfo> pageInfo;
        if (StringUtils.isBlank(request.getQueryKey())) {
            pageInfo = PageContext.startPage(request.getPageInfo().getPageNum(),
                request.getPageInfo().getPageSize());
            orgEmployeeMapper.queryEmployeeWithPermission(dataPermissionSet);
        } else {
            // 根据姓名/uid在所有员工信息中进行模糊查询（名字是加密的）
            List<Long> idList = orgEmployeeMapper.queryEmployeeWithPermission(dataPermissionSet).stream()
                .filter(employee -> StringUtils.contains(employee.getName(), request.getQueryKey())
                    || StringUtils.contains(employee.getUid(), request.getQueryKey()))
                .map(MbOrgEmployeeInfo::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(idList)) {
                return response;
            }
            pageInfo = PageContext.startPage(request.getPageInfo().getPageNum(),
                request.getPageInfo().getPageSize());
            Example example = new Example(MbOrgEmployeeInfo.class);
            example.createCriteria().andIn("id", idList);
            orgEmployeeMapper.selectByExample(example);
        }


        List<EmployeeInfoBo> result = pageInfo.getRecords().stream().map(info -> {
            EmployeeInfoBo employeeInfoBo = new EmployeeInfoBo();
            employeeInfoBo.setName(info.getName());
            employeeInfoBo.setUid(info.getUid());
            return employeeInfoBo;
        }).collect(Collectors.toList());

        PageInfoResponse page = new PageInfoResponse();
        page.setPageNum((int)pageInfo.getCurrent());
        page.setPageSize((int)pageInfo.getSize());
        page.setCount((int)pageInfo.getTotal());
        page.setTotalPage((int)pageInfo.getPages());

        response.setPageInfo(page);
        response.setList(result);

        return response;
    }

    private void trimUid(MbOrgEmployeeInfo employeeInfo){
        if(employeeInfo==null){
            return;
        }
        if(employeeInfo.getUid()!=null){
            employeeInfo.setUid(employeeInfo.getUid().trim());
        }
    }
    @Override
    public List<EmployeeInfoVo> getEmployeeInfoByUidList(List<EmployeeByUidRequestVo> request) {
        // 1 参数校验
        if (!checkEmployeeInfoRequest(request)) {
            throw new CorpBusinessException(EMPLOYEE_GET_REQUEST_IS_NULL.code(), EMPLOYEE_GET_REQUEST_IS_NULL.message());
        }

        // 2 数据查询 区分员工与外部  (正式员工0 与 非正式员工 1  外部员工 2)
        List<String> employeeUidList = new ArrayList<>();
        List<Long> nonEmployeeIdList = new ArrayList<>();
        List<EmployeeInfoVo> employeeInfoList = new ArrayList<>();
        List<EmployeeInfoVo> nonEmployeeInfoList = new ArrayList<>();
        for (EmployeeByUidRequestVo employeeByUidRequestVo : request) {
            // 员工（正式 和 非正式）
            if (Objects.equals(EMPLOYEE.getCode(), employeeByUidRequestVo.getEmployeeType())
                    || Objects.equals(INFORMAL_EMPLOYEE.getCode(), employeeByUidRequestVo.getEmployeeType())) {
                employeeUidList.add(employeeByUidRequestVo.getUid());
            }
            //外部员工
            if (Objects.equals(EXTERNAL_EMPLOYEE.getCode(), employeeByUidRequestVo.getEmployeeType())) {
                nonEmployeeIdList.add(Long.parseLong(employeeByUidRequestVo.getUid()));
            }
        }

        // 3 查询员工信息
        if (CollectionUtils.isNotEmpty(employeeUidList)){
            // 员工基础信息查询
            List<MbOrgEmployeeInfo> mbOrgEmployeeInfoList = mbOrgEmployeeLoader.selectByUids(employeeUidList);
            Map<String, MbOrgEmployeeInfo> uidEmployeeMap = mbOrgEmployeeInfoList.stream().collect(Collectors.toMap(MbOrgEmployeeInfo::getUid, Function.identity(), (e1, e2) -> e1));
            // 证件信息查询
            List<MbOrgUserIdcard> mbOrgUserIdCardList = mbOrgUserIdcardLoader.selectByUids(employeeUidList);
            Map<String, List<MbOrgUserIdcard>> uidCardMap = mbOrgUserIdCardList.stream().collect(Collectors.groupingBy(MbOrgUserIdcard::getEmployeeUid));
            // 人员组织职级关系查询
            List<MbUserOrgRelationModel> uidOrgIdRelationList = mbUserOrgRelationLoader.getRelationByUidList(employeeUidList);
            // 员工信息聚合
            employeeInfoList = assembleEmployeeInfo(employeeUidList, uidEmployeeMap, uidCardMap, uidOrgIdRelationList);
        }


        // 4 查询外部员工信息
        if (CollectionUtils.isNotEmpty(nonEmployeeIdList)) {
            List<MbOrgNonEmployeeInfo> nonEmployeeInfoDoList = mbOrgNonEmployeeLoader.selectByIds(nonEmployeeIdList);
            Map<Long, MbOrgNonEmployeeInfo> nonEmpIdInfoMap = nonEmployeeInfoDoList.stream().collect(Collectors.toMap(MbOrgNonEmployeeInfo::getId, Function.identity(), (e1, e2) -> e1));
            List<MbOrgUserIdcard> nonEmployeeIdCardList = orgUserIdCardService.batchFindByNonEmployeeUids(nonEmployeeIdList);
            Map<Long, List<MbOrgUserIdcard>> nonEmpIdCardMap = nonEmployeeIdCardList.stream().collect(Collectors.groupingBy(MbOrgUserIdcard::getNonEmployeeId));
            nonEmployeeInfoList = assembleNonEmployeeInfo(nonEmployeeIdList, nonEmpIdInfoMap, nonEmpIdCardMap);
        }

        // 结果返回
        List<EmployeeInfoVo> response = new ArrayList<>();
        response.addAll(employeeInfoList);
        response.addAll(nonEmployeeInfoList);
        return response;
    }

    @Override
    public Boolean refreshEmployeeBirthAndGender(String request) {
        log.info("refreshEmployeeBirthAndGender,start!");
        boolean result = true;
        //身份证信息查询
        List<MbOrgUserIdcard> mbOrgUserIdcards = mbOrgUserIdcardLoader.selectByCardType(Integer.parseInt(CardCodeEnum.ID_CARD.getCode()));
        HashMap<String, MbOrgUserIdcard> employeeIdCardMap = new HashMap<>();
        HashMap<Long, MbOrgUserIdcard> nonEmployeeIdCardMap = new HashMap<>();
        for (MbOrgUserIdcard mbOrgUserIdcard : mbOrgUserIdcards) {
            String employeeUid = mbOrgUserIdcard.getEmployeeUid();
            if (StringUtils.isNotBlank(employeeUid)) {
                employeeIdCardMap.putIfAbsent(employeeUid, mbOrgUserIdcard);
            }
            Long nonEmployeeId = mbOrgUserIdcard.getNonEmployeeId();
            if (Objects.nonNull(nonEmployeeId)) {
                nonEmployeeIdCardMap.putIfAbsent(nonEmployeeId, mbOrgUserIdcard);
            }
        }
        //人员信息反查
        List<String> uidList = new ArrayList<>(employeeIdCardMap.keySet());
        List<MbOrgEmployeeInfo> mbOrgEmployeeInfos = mbOrgEmployeeLoader.selectByUids(uidList);
        log.info("refreshEmployeeBirthAndGender,mbOrgEmployeeInfos:{}", mbOrgEmployeeInfos);
        List<Long> nonIdList = new ArrayList<>(nonEmployeeIdCardMap.keySet());
        List<MbOrgNonEmployeeInfo> mbOrgNonEmployeeInfos = mbOrgNonEmployeeLoader.selectByIds(nonIdList);
        log.info("refreshEmployeeBirthAndGender,mbOrgNonEmployeeInfos:{}", mbOrgNonEmployeeInfos);
        //内部员工
        for (Map.Entry<String, MbOrgUserIdcard> entry : employeeIdCardMap.entrySet()) {
            MbOrgUserIdcard value = entry.getValue();
            String cardNo = value.getCardNo();
            if (StringUtils.isBlank(cardNo)) {
                continue;
            }
            String birth = IdCardUtil.getBirth(cardNo);
            String gender = IdCardUtil.getEnGender(cardNo);
            MbOrgEmployeeInfo mbOrgEmployeeInfo = new MbOrgEmployeeInfo();
            mbOrgEmployeeInfo.setUid(value.getEmployeeUid());
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
            try {
                Date birthday = formatter.parse(birth);
                mbOrgEmployeeInfo.setBirthday(birthday);
            } catch (Exception e) {
                log.error("日期转换失败");
                continue;
            }
            mbOrgEmployeeInfo.setGender(gender);
            log.info("生日信息补充，mbOrgEmployeeInfo:{}", mbOrgEmployeeInfo);
            result = mbOrgEmployeeLoader.updateByUid(mbOrgEmployeeInfo) && result;
        }

        //外部员工
        for (Map.Entry<Long, MbOrgUserIdcard> entry : nonEmployeeIdCardMap.entrySet()) {
            MbOrgUserIdcard value = entry.getValue();
            String cardNo = value.getCardNo();
            if (StringUtils.isBlank(cardNo)) {
                continue;
            }
            MbOrgNonEmployeeInfo mbOrgNonEmployeeInfo = new MbOrgNonEmployeeInfo();
            String birth = IdCardUtil.getBirth(cardNo);
            String gender = IdCardUtil.getEnGender(cardNo);
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            try {
                Date birthday = formatter.parse(birth);
                mbOrgNonEmployeeInfo.setBirthday(birthday);
            } catch (Exception e) {
                log.info("日期转换失败");
                continue;
            }
            mbOrgNonEmployeeInfo.setId(value.getNonEmployeeId());
            mbOrgNonEmployeeInfo.setGender(gender);
            log.info("生日信息补充，mbOrgNonEmployeeInfo:{}", mbOrgNonEmployeeInfo);
            result = mbOrgNonEmployeeLoader.updateById(mbOrgNonEmployeeInfo) && result;
        }
        log.info("生日信息补充，result:{}", result);
        return result;
    }

    /**
     * 入参校验
     */
    private boolean checkEmployeeInfoRequest(List<EmployeeByUidRequestVo> request) {
        if (CollectionUtils.isEmpty(request)) {
            return false;
        }
        //uid employeeType 校验：必须都不为空
        for (EmployeeByUidRequestVo employeeUidVo : request) {
            if (StringUtils.isBlank(employeeUidVo.getUid()) || Objects.isNull(employeeUidVo.getEmployeeType())) {
                return false;
            }
            employeeUidVo.setUid(employeeUidVo.getUid().trim());
        }

        return true;
    }

    /**
     * 聚合正式非正式人员信息
     */
    private List<EmployeeInfoVo> assembleEmployeeInfo(List<String> employeeUidList, Map<String, MbOrgEmployeeInfo> uidEmployeeMap,
                                                      Map<String, List<MbOrgUserIdcard>> uidCardMap, List<MbUserOrgRelationModel> uidOrgIdRelationList) {
        List<EmployeeInfoVo> employeeInfoVoList = new ArrayList<>();
        for (String uid : employeeUidList) {
            EmployeeInfoVo employeeInfoVo = new EmployeeInfoVo();
            List<MbOrgUserIdcard> cardDoList = uidCardMap.get(uid);
            MbOrgEmployeeInfo employeeInfoDo = uidEmployeeMap.get(uid);
            if (Objects.isNull(employeeInfoDo)) {
                continue;
            }
            // 1 人员基础信息赋值
            convertEmployeeInfoDoToVo(employeeInfoVo, employeeInfoDo);
            // 2 证件信息转换和赋值
            List<EmployeeCardVo> employeeCardVos = convertEmployeeRequestDoToVo(cardDoList);
            employeeInfoVo.setCardList(employeeCardVos);

            employeeInfoVoList.add(employeeInfoVo);
        }
        // 3 组织orgId postId manageUid赋值
        setEmployeeOrgPostRelationInfo(employeeInfoVoList,uidOrgIdRelationList);
        // 4 组织信息赋值(仅员工)
        setEmployeeOrgInfo(employeeInfoVoList);
        // 5 岗位信息赋值(仅员工)
        setEmployeePostInfo(employeeInfoVoList);
        return employeeInfoVoList;
    }

    /**
     * 聚合外部人员信息
     */
    private List<EmployeeInfoVo> assembleNonEmployeeInfo(List<Long> nonEmpIdList, Map<Long, MbOrgNonEmployeeInfo> nonEmpIdInfoMap,
                                                         Map<Long, List<MbOrgUserIdcard>> nonEmpIdCardMap) {
        List<EmployeeInfoVo> nonEmployeeInfoVoList = new ArrayList<>();
        for (Long nonEmpId : nonEmpIdList) {
            EmployeeInfoVo nonEmpInfoVo = new EmployeeInfoVo();
            MbOrgNonEmployeeInfo nonEmpInfoDo = nonEmpIdInfoMap.get(nonEmpId);
            List<MbOrgUserIdcard> cardDoList = nonEmpIdCardMap.get(nonEmpId);

            if (Objects.isNull(nonEmpInfoDo)) {
                continue;
            }
            // 1 外部人员基础信息赋值
            convertNonEmployeeInfoDoToVo(nonEmpInfoVo,nonEmpInfoDo);
            // 2 证件信息赋值
            List<EmployeeCardVo> nonEmpCardVos = convertEmployeeRequestDoToVo(cardDoList);
            nonEmpInfoVo.setCardList(nonEmpCardVos);

            nonEmployeeInfoVoList.add(nonEmpInfoVo);
        }
        return nonEmployeeInfoVoList;
    }

    /**
     * 人员信息Convert (DO -> VO)
     * @param employeeInfoVo 内部员工VO
     * @param employeeInfoDo 外部员工DO
     */
    private void  convertEmployeeInfoDoToVo(EmployeeInfoVo employeeInfoVo, MbOrgEmployeeInfo employeeInfoDo){
        if (Objects.isNull(employeeInfoDo)){
            return ;
        }
        // 是否读取nameInfo的数据,T:读取  F:不读取
        boolean nameInfoReadSwitch = "T".equalsIgnoreCase(organizationApollo.getNameInfoReadSwitch());
        // 1 人员信息赋值
        if(nameInfoReadSwitch && StringUtils.isNotBlank(employeeInfoDo.getNameInfo())){
            try {
                NameInfoBo nameInfoBo = JsonUtils.parse(employeeInfoDo.getNameInfo(), NameInfoBo.class);
                employeeInfoVo.setSurname(nameInfoBo.getSurname());
                employeeInfoVo.setGivenname(nameInfoBo.getGivenname());
//            employeeInfoVo.setFullEnName(com.corpgovernment.organization.util.StrUtils.processFullEnName(nameInfoBo.getSurname(),nameInfoBo.getGivenname()));
                employeeInfoVo.setFullName(nameInfoBo.getFullName());
                employeeInfoVo.setNationality(nameInfoBo.getNationality());
            }catch (Exception e){
                log.error("人员信息转换失败,Exception:{}",e.getMessage());
            }
        }else{
            employeeInfoVo.setSurname(employeeInfoDo.getLastEnName());
            employeeInfoVo.setGivenname(employeeInfoDo.getFirstEnName());
            employeeInfoVo.setFullName(employeeInfoDo.getName());
            employeeInfoVo.setNationality(employeeInfoDo.getNationality());
        }
        employeeInfoVo.setUid(employeeInfoDo.getUid());
        employeeInfoVo.setOrgId(employeeInfoDo.getOrgId());
        employeeInfoVo.setFirstEnName(employeeInfoDo.getFirstEnName());
        employeeInfoVo.setMidEnName(employeeInfoDo.getMidEnName());
        employeeInfoVo.setLastEnName(employeeInfoDo.getLastEnName());
        // 手机号切割出国家码和手机号
        MobilePhoneVo mobilePhoneVo = employeeInfoHandleUtils.convertEmployeeMobilePhone(employeeInfoDo.getMobilePhone());
        employeeInfoVo.setTel(mobilePhoneVo);
        Date birthday = employeeInfoDo.getBirthday();
        if (Objects.nonNull(birthday)) {
            LocalDateTime localDateTime = LocalDateTime.ofInstant(birthday.toInstant(), ZoneId.systemDefault());
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String format = dtf.format(localDateTime);
            EmployeeBirthVo birth = new EmployeeBirthVo();
            birth.setValue(format);
            employeeInfoVo.setBirth(birth);
        }
        String gender = employeeInfoDo.getGender();
        employeeInfoVo.setGender(gender);
        employeeInfoVo.setShowPass(true);
        employeeInfoVo.setName(employeeInfoDo.getName());
        employeeInfoVo.setMail(employeeInfoDo.getEmail());
        employeeInfoVo.setEmployeeType(employeeInfoDo.getEmployeeType());
        employeeInfoVo.setEmployeeDesc(ApplyTripEmployeeEnum.getNameByCode(employeeInfoDo.getEmployeeType()));
    }

    /**
     * 外部人员信息Convert (DO -> VO)
     */
    private void  convertNonEmployeeInfoDoToVo(EmployeeInfoVo employeeInfoVo, MbOrgNonEmployeeInfo nonEmpInfoDo){
        if (Objects.isNull(nonEmpInfoDo)){
            return ;
        }
        // 是否读取nameInfo的数据,T:读取  F:不读取
        boolean nameInfoReadSwitch = "T".equalsIgnoreCase(organizationApollo.getNameInfoReadSwitch());
        // 1 人员信息赋值
        if(nameInfoReadSwitch && StringUtils.isNotBlank(nonEmpInfoDo.getNameInfo())){
            try {
                NameInfoBo nameInfoBo = JsonUtils.parse(nonEmpInfoDo.getNameInfo(), NameInfoBo.class);
                employeeInfoVo.setSurname(nameInfoBo.getSurname());
                employeeInfoVo.setGivenname(nameInfoBo.getGivenname());
//            employeeInfoVo.setFullEnName(com.corpgovernment.organization.util.StrUtils.processFullEnName(nameInfoBo.getSurname(),nameInfoBo.getGivenname()));
                employeeInfoVo.setFullName(nameInfoBo.getFullName());
                employeeInfoVo.setNationality(nameInfoBo.getNationality());
            }catch (Exception e){
                log.error("人员信息转换失败,Exception:{}",e.getMessage());
            }
        }else{
            employeeInfoVo.setSurname(nonEmpInfoDo.getLastEnName());
            employeeInfoVo.setGivenname(nonEmpInfoDo.getFirstEnName());
            employeeInfoVo.setFullName(nonEmpInfoDo.getName());
            employeeInfoVo.setNationality(nonEmpInfoDo.getNationality());
        }
        employeeInfoVo.setNoEmployeeId(nonEmpInfoDo.getId().toString());
        employeeInfoVo.setFirstEnName(nonEmpInfoDo.getFirstEnName());
        employeeInfoVo.setMidEnName(nonEmpInfoDo.getMidEnName());
        employeeInfoVo.setLastEnName(nonEmpInfoDo.getLastEnName());
        // 手机号切割出国家码和手机号
        MobilePhoneVo mobilePhoneVo = employeeInfoHandleUtils.convertEmployeeMobilePhone(nonEmpInfoDo.getMobilePhone());
        employeeInfoVo.setTel(mobilePhoneVo);
        Date birthday = nonEmpInfoDo.getBirthday();
        if (Objects.nonNull(birthday)) {
            LocalDateTime localDateTime = LocalDateTime.ofInstant(birthday.toInstant(), ZoneId.systemDefault());
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String format = dtf.format(localDateTime);
            EmployeeBirthVo birth = new EmployeeBirthVo();
            birth.setValue(format);
            employeeInfoVo.setBirth(birth);
        }
        String gender = nonEmpInfoDo.getGender();
        employeeInfoVo.setGender(gender);
        employeeInfoVo.setShowPass(true);
        employeeInfoVo.setName(nonEmpInfoDo.getName());
        employeeInfoVo.setMail(nonEmpInfoDo.getEmail());
        employeeInfoVo.setEmployeeType(nonEmpInfoDo.getEmployeeType());
        employeeInfoVo.setEmployeeDesc(ApplyTripEmployeeEnum.getNameByCode(nonEmpInfoDo.getEmployeeType()));
    }


    /**
     * 人员证件信息Convert (DO -> VO)
     */
    private List<EmployeeCardVo> convertEmployeeRequestDoToVo(List<MbOrgUserIdcard> cardDoList){
        if (CollectionUtils.isEmpty(cardDoList)){
            return null;
        }
        List<EmployeeCardVo> cardVoList = new ArrayList<>();
        for (MbOrgUserIdcard cardDo : cardDoList) {
            EmployeeCardVo cardVo = new EmployeeCardVo();
            cardVo.setValue(cardDo.getCardNo());
            cardVo.setType(cardDo.getCardType());
            Date timeLimit = cardDo.getTimeLimit();
            // 证件是否有效
            if (timeLimit != null) {
                cardVo.setIsValid(timeLimit.after(new Date()));
            } else {
                cardVo.setIsValid(false);
            }
            cardVo.setValidity(timeLimit);
            cardVo.setName(CardTypeSwitchUtil.getNameById(cardDo.getCardType()));
            cardVo.setPlaceOfIssue(cardDo.getPlaceOfIssue());
            cardVo.setIssueAtPlace(cardDo.getIssueAt());
            cardVo.setPassportType(cardDo.getPassportType());
            cardVoList.add(cardVo);
        }

        return cardVoList;
    }

    /**
     * 根据 Uid赋值人员组织岗位关联信息
     */
    private void setEmployeeOrgPostRelationInfo(List<EmployeeInfoVo> employeeInfoVoList, List<MbUserOrgRelationModel> uidOrgIdRelationList){
        if (CollectionUtils.isEmpty(uidOrgIdRelationList)){
            return;
        }
        Map<String, MbUserOrgRelationModel> uidOrgIdRelationMap = uidOrgIdRelationList.stream().collect(Collectors.toMap(MbUserOrgRelationModel::getUid, Function.identity(), (e1, e2) -> e1));
        employeeInfoVoList.forEach(info -> {
            String uid = info.getUid();
            MbUserOrgRelationModel relation = uidOrgIdRelationMap.getOrDefault(uid, null);
            info.setOrgId(relation.getOrgId());
            info.setPostId(relation.getPostId());
            info.setPositionStatus(relation.getStatus());
            info.setManageUid(relation.getManageUid());
        });
    }

    /**
     * 根据 Uid赋值人员组织信息
     */
    private void setEmployeeOrgInfo(List<EmployeeInfoVo> employeeInfoVoList){
        if (CollectionUtils.isEmpty(employeeInfoVoList)){
            return;
        }
        List<String> orgIdList = employeeInfoVoList.stream().map(EmployeeInfoVo::getOrgId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(orgIdList)){
            return;
        }
        List<MbOrgInfo> mbOrgInfoDoList = mbOrgInfoLoader.selectByOrgIds(orgIdList);
        Map<String, MbOrgInfo> orgInfoMap = mbOrgInfoDoList.stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, Function.identity(), (e1, e2) -> e1));
        for (EmployeeInfoVo employeeInfoVo : employeeInfoVoList) {
            String orgId = employeeInfoVo.getOrgId();
            if (StringUtils.isNotBlank(orgId) && orgInfoMap.containsKey(orgId)){
                MbOrgInfo mbOrgInfo = orgInfoMap.get(orgId);
                if (Objects.nonNull(mbOrgInfo)) {
                    employeeInfoVo.setOrgName(mbOrgInfo.getName());
                    employeeInfoVo.setOrgId(mbOrgInfo.getOrgId());
                    employeeInfoVo.setOrgType(mbOrgInfo.getOrgType());
                }
            }
        }
    }
    /**
     * 根据 Uid赋值人员岗位信息
     */
    private void setEmployeePostInfo(List<EmployeeInfoVo> employeeInfoVoList){
        if (CollectionUtils.isEmpty(employeeInfoVoList)){
            return;
        }
        List<Long> postIdList = employeeInfoVoList.stream().map(EmployeeInfoVo::getPostId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(postIdList)){
            return;
        }
        List<MbPostInfo> postInfoDoList = mbPostMapper.selectByPostIds(postIdList);
        Map<Long, MbPostInfo> postInfoMap = postInfoDoList.stream().collect(Collectors.toMap(MbPostInfo::getId, Function.identity(), (e1, e2) -> e1));
        employeeInfoVoList.forEach(info -> {
            Long postId = info.getPostId();
            if (Objects.nonNull(postId) && postInfoMap.containsKey(postId)) {
                MbPostInfo mbOrgInfo = postInfoMap.get(postId);
                if (Objects.nonNull(mbOrgInfo)) {
                    info.setPostName(mbOrgInfo.getName());
                    info.setPostCode(mbOrgInfo.getCode());
                    info.setPostAllowance(mbOrgInfo.getAllowance());
                    info.setPostRights(mbOrgInfo.getRights());
                }
            }
        });
    }

    @Override
    public ListEmployeeByConditionResponse listEmployeeByCondition(ListEmployeeByConditionRequest request) {
        ListEmployeeByConditionResponse response = new ListEmployeeByConditionResponse();
        // 将部分搜索条件转换为uidList
        List<String> queryUidList = convertUidFormRequest(request);
        List<MbOrgEmployeeInfo> employeeInfoList = CollectionUtils.newArrayList();
        // queryUidList为空则说明未搜到任何结果，为null说明未传入以上搜索条件
        if (Objects.isNull(queryUidList) || CollectionUtils.isNotEmpty(queryUidList)){
            //搜索员工信息表
            employeeInfoList = mbOrgEmployeeLoader.listByCondition(request, queryUidList);
        }
        // 数据权限过滤
        List<String> uidPermissionList = listUidByPermission();
        employeeInfoList = employeeInfoList.stream().filter(e -> uidPermissionList.contains(e.getUid())).collect(Collectors.toList());
        // 处理分页
        employeeInfoList = dealPage(employeeInfoList, request, response);
        // 查询uid关联的组织信息
        List<String> uidList = employeeInfoList.stream().map(MbOrgEmployeeInfo::getUid).collect(Collectors.toList());
        List<MbUserOrgRelationModel> orgRelationList = mbUserOrgRelationLoader.getRelationByUidList(uidList);
        Map<String, MbUserOrgRelationModel> orgRelationMap = orgRelationList.stream().collect(Collectors.toMap(MbUserOrgRelationModel::getUid, e -> e, (k1, k2) -> k1));
        // 组装初步的结果集合
        List<EmployeeInfoConditionVO> list = employeeInfoBasicConvert(employeeInfoList, orgRelationMap);
        // 组装岗位信息
        uidList = list.stream().map(EmployeeInfoConditionVO::getUid).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(uidList)) {
            Map<String, JobDo> uidJobMap = jobService.getUidJobMap(uidList);
            employeeJobInfoConvert(list, uidJobMap);
        }
        // 组装org信息
        List<String> orgIdList = list.stream().map(EmployeeInfoConditionVO::getOrgId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(orgIdList)) {
            Map<String, MbOrgInfo> orgInfoMap = orgInfoMapper.selectByOrgIds(orgIdList).stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, e -> e, (k1, k2) -> k1));
            employeeOrgInfoConvert(list, orgInfoMap);
        }
        // 组装post信息
        List<Long> postIdList = list.stream().map(EmployeeInfoConditionVO::getPostId).filter(Objects::nonNull).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(postIdList)) {
            Map<Long, MbPostInfo> postMap = mbPostMapper.selectByPostIds(postIdList).stream().collect(Collectors.toMap(MbPostInfo::getId, e -> e, (k1, k2) -> k1));
            employeePostInfoConvert(list, postMap);
        }
        // 组装证件信息
        if (CollectionUtils.isNotEmpty(uidList)) {
            Map<String, List<MbOrgUserIdcard>> idCardMap = organizationUserIdCardService.batchFindByUids(uidList).stream().collect(Collectors.groupingBy(MbOrgUserIdcard::getEmployeeUid));
            employeeCardInfoConvert(list, idCardMap);
        }
        // 组装角色信息
        if (CollectionUtils.isNotEmpty(list)) {
            List<Pair<String, String>> uidOrgIds = new ArrayList<>();
            list.forEach(e -> {
                uidOrgIds.add(Pair.of(e.getUid(), e.getOrgId()));
            });
            Map<Pair<String, String>, List<Long>> empRoleMap = queryEmpRoleByUidAndOrgId(uidOrgIds);
            Map<Long, String> roleIdNameMap = roleService
                    .batchSearchRoleName(empRoleMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet()));
            employeeRoleInfoConvert(list, empRoleMap, roleIdNameMap);
        }
        // 组装组织树名称列表
        if (CollectionUtils.isNotEmpty(list)) {
            employeeOrgTreeNameConvert(list);
        }
        response.setEmployeeInfoList(list);
        return response;
    }

    private List<String> listUidByPermission() {
        List<String> orgIdPermissionList = listOrgInfoByPermission();
        if (CollectionUtils.isEmpty(orgIdPermissionList)){
            return CollectionUtils.newArrayList();
        }
        List<MbUserOrgRelationModel> userOrgRelationList = mbUserOrgRelationLoader.getRelationByOrgIdListNew(orgIdPermissionList);
        return userOrgRelationList.stream().map(MbUserOrgRelationModel::getUid).collect(Collectors.toList());
    }

    private List<MbOrgEmployeeInfo> dealPage(List<MbOrgEmployeeInfo> employeeInfoList, ListEmployeeByConditionRequest request, ListEmployeeByConditionResponse response) {
        PageInfoResponse pageInfo = request.getPageInfo();
        // 无分页信息则全部返回
        if (Objects.isNull(pageInfo) || Objects.isNull(pageInfo.getPageNum()) || Objects.isNull(pageInfo.getPageSize())){
            return employeeInfoList;
        }
        int pageSize = pageInfo.getPageSize();
        int pageNum = pageInfo.getPageNum();
        int count = employeeInfoList.size();
        int totalPage = (count + pageSize - 1) / pageSize;
        pageInfo.setCount(count);
        pageInfo.setTotalPage(totalPage);
        response.setPageInfo(pageInfo);
        // 超页返回空
        if (pageNum > totalPage){
            return CollectionUtils.newArrayList();
        } else {
            return employeeInfoList.stream().skip((long) (pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        }
    }

    private List<String> convertUidFormRequest(ListEmployeeByConditionRequest request) {
        List<String> uidList = null;
        if (CollectionUtils.isNotEmpty(request.getOrgIdList()) || CollectionUtils.isNotEmpty(request.getPostIdList()) || Objects.nonNull(request.getStatus())){
            uidList = CollectionUtils.newArrayList();
            List<MbUserOrgRelationModel> userOrgRelationList = mbUserOrgRelationLoader.listByCondition(request.getOrgIdList(), request.getPostIdList(), request.getStatus());
            uidList.addAll(userOrgRelationList.stream().map(MbUserOrgRelationModel::getUid).collect(Collectors.toList()));
        }
        if (CollectionUtils.isNotEmpty(request.getJobIdList())){
            List<EmployeeJobRelationDo> employeeJobRelationList = employeeJobRelationLoader.listEmployeeJobRelationByJobIdList(request.getJobIdList());
            if (Objects.isNull(uidList)){
                uidList = CollectionUtils.newArrayList();
            }
            uidList.addAll(employeeJobRelationList.stream().map(EmployeeJobRelationDo::getUid).collect(Collectors.toList()));
        }
        return uidList;
    }

    private void employeeOrgTreeNameConvert(List<EmployeeInfoConditionVO> list) {
        Map<String, MbOrgInfo> orgIdMap = organizationInfoService.listAll().stream().collect(Collectors.toMap(MbOrgInfo::getOrgId, e -> e, (k1, k2) -> k1));
        list.forEach(e ->{
            ArrayList<String> orgTreeNameList = new ArrayList<>();
            orgTreeNameConvert(e.getOrgId(), orgTreeNameList, orgIdMap, MAX_RECURSION_TIMES);
            Collections.reverse(orgTreeNameList);
            e.setOrgTreeNameList(orgTreeNameList);
        });
    }

    private void orgTreeNameConvert(String orgId, ArrayList<String> orgTreeNameList, Map<String, MbOrgInfo> orgIdMap, Integer maxRecursionTimes) {
        if (maxRecursionTimes < 0){
            return;
        }
        MbOrgInfo orgInfo = orgIdMap.get(orgId);
        if (Objects.isNull(orgInfo)){
            return;
        }
        orgTreeNameList.add(orgInfo.getName());
        if (Objects.isNull(orgInfo.getParentId())){
            return;
        }
        orgTreeNameConvert(orgInfo.getParentId(), orgTreeNameList, orgIdMap, maxRecursionTimes - 1);
    }

    private void employeeRoleInfoConvert(List<EmployeeInfoConditionVO> list, Map<Pair<String, String>, List<Long>> empRoleMap, Map<Long, String> roleIdNameMap) {
        list.forEach(e ->{
            List<Long> roleIds = empRoleMap.getOrDefault(Pair.of(e.getUid(), e.getOrgId()), Collections.emptyList());
            if (CollectionUtils.isNotEmpty(roleIds)){
                String roleName = roleIds.stream().map(roleIdNameMap::get).filter(Objects::nonNull).collect(Collectors.joining(","));
                e.setRole(roleName);
            }
        });
    }

    private Map<Pair<String, String>, List<Long>> queryEmpRoleByUidAndOrgId(List<Pair<String, String>> uidOrgIds){
        // 查询员工的角色,每500个一组查询
        Map<Pair<String, String>, List<Long>> empRoleMap = Maps.newHashMapWithExpectedSize(uidOrgIds.size());
        List<CompletableFuture<Map<Pair<String, String>, List<Long>>>> features =
                Lists.partition(uidOrgIds, 500).stream()
                        .map(uidOrgIdGroup -> CompletableFuture.supplyAsync(
                                () -> roleService.batchSearchUserRoleIdByUidAndOrgId(uidOrgIdGroup), defaultThreadPoolExecutor))
                        .collect(Collectors.toList());
        try {
            CompletableFuture.allOf(features.toArray(new CompletableFuture[] {})).get(15, TimeUnit.SECONDS);
            for (CompletableFuture<Map<Pair<String, String>, List<Long>>> feature : features) {
                empRoleMap.putAll(feature.get());
            }
        } catch (Exception e) {
            log.error("导出员工信息查询员工角色出现异常", e);
            throw new com.ctrip.corp.obt.generic.exception.CommonException(DOWNLOAD_EMPLOYEE_INFO_ERROR);
        }
        return empRoleMap;
    }

    private void employeeCardInfoConvert(List<EmployeeInfoConditionVO> list, Map<String, List<MbOrgUserIdcard>> idCardMap) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(idCardMap)){
            return;
        }
        list.forEach(e ->{
            List<MbOrgUserIdcard> orgUserIdCardList = idCardMap.get(e.getUid());
            if (CollectionUtils.isNotEmpty(orgUserIdCardList)){
                ArrayList<UserIdCardVo> cardList = new ArrayList<>();
                orgUserIdCardList.forEach(k ->{
                    UserIdCardVo card = new UserIdCardVo();
                    card.setCardType(k.getCardType());
                    card.setCardNo(k.getCardNo());
                    card.setPlaceOfIssue(k.getPlaceOfIssue());
                    card.setIssueAt(k.getIssueAt());
                    card.setPassportType(k.getPassportType());
                    card.setTimeLimit(k.getTimeLimit());
                    cardList.add(card);
                });
                e.setCardList(cardList);
            }
        });
    }

    private void employeePostInfoConvert(List<EmployeeInfoConditionVO> list, Map<Long, MbPostInfo> postMap) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(postMap)){
            return;
        }
        list.forEach(e ->{
            MbPostInfo postInfo = postMap.get(e.getPostId());
            if (Objects.nonNull(postInfo)){
                e.setPostName(postInfo.getName());
            }
        });
    }

    private void employeeOrgInfoConvert(List<EmployeeInfoConditionVO> list, Map<String, MbOrgInfo> orgInfoMap) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(orgInfoMap)){
            return;
        }
        list.forEach(e ->{
            MbOrgInfo orgInfo = orgInfoMap.get(e.getOrgId());
            if (Objects.nonNull(orgInfo)){
                e.setOrgName(orgInfo.getName());
            }
        });
    }

    private void employeeJobInfoConvert(List<EmployeeInfoConditionVO> list, Map<String, JobDo> uidJobMap) {
        if (CollectionUtils.isEmpty(list) || CollectionUtils.isEmpty(uidJobMap)){
            return;
        }
        list.forEach(e ->{
            JobDo job = uidJobMap.get(e.getUid());
            if (Objects.nonNull(job)){
                e.setJobId(job.getId());
                e.setJobName(job.getName());
            }
        });
    }

    private List<EmployeeInfoConditionVO> employeeInfoBasicConvert(List<MbOrgEmployeeInfo> employeeInfoList, Map<String, MbUserOrgRelationModel> orgRelationMap) {
        List<EmployeeInfoConditionVO> list = CollectionUtils.newArrayList();
        if (CollectionUtils.isEmpty(employeeInfoList) || CollectionUtils.isEmpty(orgRelationMap)){
            return list;
        }
        employeeInfoList.forEach(e ->{
            MbUserOrgRelationModel userOrgRelation = orgRelationMap.get(e.getUid());
            // 找不到对应组织信息则认为是无效数据
            if (Objects.nonNull(userOrgRelation)) {
                EmployeeInfoConditionVO vo = new EmployeeInfoConditionVO();
                vo.setName(e.getName());
                vo.setUid(e.getUid());
                vo.setPhoneNum(e.getMobilePhone());
                vo.setEmployeeType(e.getEmployeeType());
                vo.setOrgId(userOrgRelation.getOrgId());
                vo.setStatus(userOrgRelation.getStatus());
                vo.setCheckLeader(1 == userOrgRelation.getIsLeader());
                vo.setPostId(userOrgRelation.getPostId());
                list.add(vo);
            }
        });
        return list;
    }

    private List<String> listOrgInfoByPermission(){
        // 获取当前登录用户权限下所有orgId
        BaseUserInfo userInfo = UserInfoContext.getContextParams(BaseUserInfo.class);
        Set<String> dataPermissionSet = null;
        // 判断是否是admin用户，如果是，则返回全量数据
        if (Boolean.TRUE.equals(userInfo.getBgUser())) {
            // admin使用else中的方法返回的数据为0
            return mbOrgInfoMapper
                    .listAll().stream().map(MbOrgInfo::getOrgId).distinct().collect(Collectors.toList());
        } else {
            // 当前登录用户权限下所有orgId
            return Optional.ofNullable(DataPermissionsContext.getRoleAllDataPermissions())
                    .map(ResourceInfo::getDeptInfos).orElse(new ArrayList<>()).stream().map(ResourceInfo.DeptInfo::getOrgId)
                    .distinct().collect(Collectors.toList());
        }
    }
}